2013-05-22 61 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