2016-01-26 103 views
8

今天,我不得不修復由此引起的代碼性能問題:注重updateStats稱爲模板中函數被調用多次(角JS)

<script type="text/ng-template" id="entityGrouper"> 

<section> 

<div> 
<ul ng-click="hideEntityBox = !hideEntityBox"> 
<li> 
{{ entityNode.name }} 
</li> 
<li ng-repeat="breadcrumbItem in entityNode.breadcrumb"> 
{{ breadcrumbItem }} 
</li> 
</ul> 
{{ updateStats(entityNode) }} 
<span ng-include="'/mypath/views/resume.html'"></span> 
</div> 

<div> 

<div ng-repeat="entityNode in entityNode.group" ng-include="'entityGrouper'"></div> 
<div ng-repeat="entity in entityNode.group" ng-include="'entityBox'"></div> 

</section> 

</script> 

模板使用:

<div ng-repeat="entityNode in entityNode.group" ng-include="'entityGrouper'"></div> 

調試完這段代碼之後,我發現這個函數調用的時間比數組大小多(我的數組有4個對象,函數被調用超過100次),甚至鼠標懸停都稱爲此函數。 我解決了這個問題,只需在模板中放入一個ng-init,現在它工作正常,但我沒有弄清楚爲什麼這個函數被調用了很多次。有兩種數據綁定方式嗎?

+0

你遞歸調用相同的模板?還有一個'

'內部模板 – Developer

回答

1

發生這種情況不是因爲雙向數據綁定(它可適用於形成輸入),而是角度變化的檢測,因爲。 Angular定期檢查綁定到模板的任何值是否更改,如果是,則更新其在視圖中的值。通常,它由用戶生成的事件觸發。爲了檢查updateStats(entityNode)的值是否發生了變化,Angular會對它進行評估,這會導致性能下降。

若要解決此問題,您可以使用前面提到的一次性綁定updateStats(entityNode)如果結果設置一次並且將來不會更改。我想,這是你的情況,你已經將評估移至ng-init。對於隨時間更新的值,最好在entityNode(如entityNode.stats)中創建單獨的屬性,將其顯示在模板中,並僅在需要時在控制器或服務中運行updateStats(entityNode)。通過這樣做,您將防止在每個摘要循環中運行updateStats(entityNode)(您已經看到了這種情況的頻率),從而提高了應用程序的性能。

4

對於這樣的場景,通常建議使用$watch。由於您綁定了一個函數{{updateStats()}},它將在每個摘要循環中執行。

因此,在您的代碼中,每當調用摘要循環時,它也會調用該函數。消化週期在Angular中經常被內部調用。

+0

這個應該是被接受的正確答案 – thiagoh

2

你所看到的是消化循環的結果。

添加一個::將調用該函數一次/一次綁定。

{{ ::updateStats(entityNode) }}

+0

什麼::正確地做? –

+1

'::'提供一次性綁定。如果你用這個前綴表達式,它將停止運行或在第一個摘要之後重新計算。更多信息* [文檔](https://docs.angularjs.org/guide/expression)的一次性綁定*部分。 –