angular中文 - angularjs介紹



如何使用ng-repeat循環遍歷函數返回的項目? (3)

簡短的回答 :你真的需要這樣的功能,或者你可以使用財產? http://jsfiddle.net/awnqm/1/

長答案

為了簡單起見,我將只描述你的情況 - 對像數組的ngRepet。 另外,我會省略一些細節。

AngularJS使用臟檢查來檢測變化。 當應用程序啟動時,它為$rootScope運行$digest$digest將為作用域的層次結構執行深度優先遍歷。 所有範圍都有手錶列表。 每個手錶都有最後一個值(最初為initWatchVal )。 對於所有手錶的$digest運行它,獲取當前值( watch.get(scope) )並將其與watch.last進行比較。 如果當前值不等於watch.last (始終用於第一個比較) $digestdirty設置為true 。 當所有的作用域被處理時,如果dirty == true $digest$rootScope開始另一個深度優先遍歷。 $digest在dirty == false或遍歷數為10時結束。在後一種情況下,錯誤“10 $ digest()迭代到達”。 將被記錄。

現在關於ngRepeat 。 對於每個watch.get調用它將來自collection的對象(返回getEntities值)與緩存中的HashQueueMap信息( HashQueueMaphashKey )一起存儲。 對於每個watch.get調用ngRepeat嘗試通過緩存中的hashKey獲取對象。 如果它不存在於緩存中, ngRepeat將它存儲在緩存中,創建新的作用域,將對象放在緩存中,創建DOM元素etc

現在關於hashKey 。 通常, hashKey是由nextUid()生成的唯一編號。 但它可以是functionhashKey在生成後存儲在對像中以供將來使用。

為什麼你的例子產生錯誤 :函數getEntities()總是返回具有新對象的數組。 該對像沒有hashKey ,並且不存在於ngRepeat緩存中。 因此,每個ngRepeat上的watch.get{{entity.id}}新手錶生成新的範圍。 第一個watch.get上的該手錶具有watch.last == initWatchVal 。 所以watch.get() != watch.last 。 所以$digest開始新的遍歷。 所以ngRepeat用新手錶創建新的範圍。 所以......經過10次遍歷後你會得到錯誤。

你如何解決它

  1. 不要在每個getEntities()調用中創建新的對象。
  2. 如果你需要創建新的對象,你可以為它們添加hashKey方法。 有關示例,請參閱此主題

希望那些了解AngularJS內部構件的人糾正我,如果我在某些方面有錯誤的話。

我想重複創建div,這些項目是由函數返回的對象。 但是,以下代碼報告錯誤:已達到10次摘要()迭代。 中止! jsfiddle在這裡: http://jsfiddle.net/BraveOstrich/awnqm/ : http://jsfiddle.net/BraveOstrich/awnqm/

<body ng-app>
  <div ng-repeat="entity in getEntities()">
    Hello {{entity.id}}!
  </div>
</body>

Answer #1

在重複之外初始化數組

<body ng-app>
   <div ng-init="entities = getEntities()">
       <div ng-repeat="entity in entities">
           Hello {{entity.id}}!
       </div>
   </div>
</body>

Answer #2

這是在這里報道並得到了這樣的回應:

你的getter不是冪等的並且改變了模型(每次調用時都會生成一個新的數組)。 這迫使角度繼續調用它,希望模型最終能穩定下來,但它永遠不會放棄角色並拋出異常。

吸氣劑返回值相等但不相同,這就是問題所在。

如果將陣列移到主控制器外部,您可以看到這種行為消失:

var array = [{id:'angularjs'}];
function Main($scope) {
    $scope.getEntities = function(){return array;};
};

因為現在它每次都返回相同的對象。 您可能需要重新構建您的模型,以便在範圍中使用屬性而不是函數:

我們通過將控制器的方法的結果分配給一個屬性來解決這個問題,然後執行ng:repeat。





angularjs