2014-02-05 54 views
5

使用隨機orderBy排序技術this question在AngularJS 1.1中正常工作。隨機orderBy in AngularJS 1.2返回'infdig'錯誤

var myApp = angular.module('myApp',[]); 

function MyCtrl($scope) { 
    $scope.list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']; 
    $scope.random = function() { 
     return 0.5 - Math.random(); 
    } 
} 

在1.2,雖然,它把infdig錯誤到控制檯和需要更長的時間才能返回排序結果:http://jsfiddle.net/mblase75/jVs27/

在控制檯中的錯誤是這樣的:

Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! 
Watchers fired in the last 5 iterations: [["fn: $watchCollectionWatch; newVal: 42; oldVal: 36"],["fn: $watchCollectionWatch; newVal: 47; oldVal: 42"],["fn: $watchCollectionWatch; newVal: 54; oldVal: 47"],["fn: $watchCollectionWatch; newVal: 61; oldVal: 54"],["fn: $watchCollectionWatch; newVal: 68; oldVal: 61"]] 

The documentation for orderBy沒有使用函數表達式的例子,只有字符串表達式。有沒有改變,或者這是一個錯誤?

+0

更新:[錯誤提交](https://github.com/angular/angular.js/issues/6133#issuecomment-34229877)導致內部發生了什麼情況的解釋。 – Blazemonger

回答

9

我不確定以前的版本,但在當前版本中,在範圍上觀看的任何表達式(例如傳遞給ng-repeat的表達式)通常每個摘要至少評估兩次。僅當整個Angular應用程序的所有範圍內的所有評估表達式的結果在兩次連續評估之間相同時,摘要週期纔會結束。

因爲在調用的

<li ng-repeat="i in list | orderBy:random">{{i}}</li> 

結果每個評估隨機的()等不同的順序,那麼角將繼續評估該表達式,直到達到其10極限消化迭代,並拋出一個錯誤。

對此的解決辦法是設置的順序模板之外,在控制器:通過類似

$scope.list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']; 
$scope.rankedList = []; 
angular.forEach($scope.list, function(item) { 
    $scope.rankedList.push({ 
     item: item, 
     rank: 0.5 - $window.Math.random() 
    }); 
}); 

然後爲了使用領域:

<li ng-repeat="i in rankedList | orderBy:'rank'">{{i.item}}</li> 

由此可以看出在這jsfiddle

+0

好的答案 - 我通過將'隨機排名'生成器放在一個範圍函數中,讓我更進一步,所以我可以通過'ng-click'在需要的應用程序中觸發它。 – Blazemonger

+0

我簡化了這一點,只需在現有數組中添加一個「rank」值,而不是創建一個新的「排名」數組。感謝這個想法, –

2

您可以使用簡單的自定義過濾器以角度方式解決此問題。在這裏,我使用了實現Fischer-Yates的下劃線混洗方法。

如果你願意,你可以用你自己的算法替換shuffle的膽量。

angular.module('shuffle', []) 
    .filter('shuffle', function() { 
    return function(ary) { 
     return _.shuffle(ary); 
    } 
    }); 

現在我們可以管我們的陣列通過這個過濾器,像這樣:

<li ng-repeat='option in options | shuffle'> 

當模板被渲染的過濾器將被調用一次。

+0

我沒有使用Underscore。 – Blazemonger

+0

你可以替代lodash。 – superluminary

+1

如果你喜歡,你可以編寫自己的shuffle函數,但由於混洗是一個解決的問題,我認爲這是使用庫的好時機。 – superluminary