2013-05-22 31 views
16

我在Angular.JS中使用路由器(正在使用内置的一个,现在使用ui-route,但解决方案都可以),以在控件/模板对之间进行切换。当在这些页面之间来回切换时,每次看起来都很糟糕,需要花费一秒时间来设置DOM。反正有角度保持在DOM树周围,而不是每次重新创建它。我想我只想隐藏/播种每个页面的位,而不是每次删除/重新创建它们。在Angular.JS中缓存DOM

欢迎任何建议!

+2

您可以用[ng-show](http://docs.angularjs.org/api/ng.directive:ngShow)隐藏/显示区域。你也可能想看看[$ templateCache](http://docs.angularjs.org/api/ng.$templateCache),它可以让你缓存你的视图。 –

+0

我想我可以使用ng-show,但是那样我就不必扔掉Angular提供的洞路由器和url管理了吗?不完全确定如何使用$ templateCache,我可以设置所有模板缓存吗? –

+0

你可以使用两个ng-app来管理我猜测的两种行为。 – GnrlBzik

回答

4

你必须编写自己的ng-view指令来创建这样的功能。

其背后的基本思想是:

路线更改之前,而不是破坏当前视图元素,范围,你只要把它放在一个看不见的缓存DIV,并注销范围的听众。给该元素一个数据属性$$route.templateUrl能够恢复。 然后您从服务器获取下一个视图。

路线改变您检查缓存项所有脑干,如果它在你的缓存DIV从缓存中获取元素,重新注册的听众,并把当前视图缓存之前。

棘手的部分是不要惹的$scope s提高。因此,您可能需要在$scope中为该事件创建构造函数和析构函数,也可能需要$ watchers。我不确定。

但说实话,如果你使用模板缓存,并且仍然需要1秒左右的渲染,那么你可能会有一些低效的$watch表达式,或者一个巨大的ng-repeat。你应该考虑一些事实。

+1

+1表示最后一段中的表现评论 – w00t

+0

难道真的能帮助某人解决真正的问题吗?如果有人提供示例,它如何与代码一起工作会很好。 – alexche8

0

如果向上移动到角1.1.5,您可以使用NG-动画属性你NG-view标记。

我不是100%肯定,但我认为它会做一些DOM缓存,使过渡更好地工作。你可以尝试添加添加ng-animate属性到你的标签。这可能会帮你照顾它。

2

我一直在研究这个我自己。我正在一个不加速的浏览器中使用相当旧的硬件。初始渲染是一个问题。正如您尝试的那样,我的早期解决方法是缓存预编译的模板。我发现这只能提供最小的速度提升。

真正的瓶颈是从我NG重复指令的到来,这导致回流的数量和DOM节点/观察家我是建立在每个迭代次数。

有些来源建议创建一个自定义指令,手动组装dom并一次添加它。结果是回流很小,没有观察者。缺点是非常大。没有更多的角色乐趣和很多不必要的工作。更重要的是,这些都没有提供足够的速度改进来证明工作的合理性。

我最终发现,最好的速度提高来自于对每个ng-repeat迭代强制进行硬件加速。如上所述,新版本中的ng-animate指令使得这个相对来说不重要。

你会看到立即页面渲染,轻微的回流打嗝。 ng-cloak在这里没有帮助。由于动画请求,页面不会在重复呈现时隐藏起来。然而,这些可以通过一些聪明的乐趣来合理地呈现出来。我实际上隐藏了ng-repeat,直到$ location改变,同时显示进度指示器,然后切换我的ng显示。这工作非常好。

说了这么多,预编译你的模板应该按如下方式完成。

1)当你的应用程序启动时,为自己创建一个新的缓存。请参阅http://docs-angularjs-org-dev.appspot.com/api/ng。$ cacheFactory

2)用编译模板填充此缓存。注入$ compile并在每个模板上调用它。编译返回一个函数,您稍后将调用您的范围。如果您认为合适,请在缓存中键入此功能。

3)创建一个接受缓存键作为属性的自定义指令。在这个指令中,查询你的编译缓存是否有正确的编译函数。根据当前范围调用该函数,并将生成的DOM附加到传递给该指令的元素。

4)Sorta win :)。

+0

你能指导我如何做第3部分?查询我们编译缓存的正确编译功能? – Salman

+1

这种方法有一些生动的例子吗? 这里隐藏着很多东西: – yccteam