看起来真正的问题是您正在更改输入,而不是创建新变量并从过滤器中输出。这将触发任何正在监视您输入的变量的监视。
确实没有理由在其中添加“grouped == true”检查,因为您应该完全控制自己的过滤器。但是,如果这对您的应用程序来说是必须的,那么您需要将“grouped == true”添加到过滤器的结果中,而不是输入中。
过滤器的工作方式是它们改变输入并返回不同的东西,然后下一个过滤器处理以前的过滤器结果......所以你的“过滤”检查item in items | filter1 | filter2 | filter3
在 filter1 过滤项目,filter2 过滤 filter1 的结果和filter3 过滤过滤器 2 的结果...如果有意义的话。
这是我刚刚整理的东西。我不确定(还)它是否有效,但它给了你基本的想法。您将在一侧取出一个数组,然后在另一侧吐出一组数组。
app.filter('group', function(){
return function(items, groupSize) {
var groups = [],
inner;
for(var i = 0; i < items.length; i++) {
if(i % groupSize === 0) {
inner = [];
groups.push(inner);
}
inner.push(items[i]);
}
return groups;
};
});
HTML
<ul ng-repeat="grouping in items | group:3">
<li ng-repeat="item in grouping">{{item}}</li>
</ul>
编辑
也许在代码中看到所有这些过滤器会更好,但它看起来会导致问题,因为它经常需要在 $digest 上重新评估。所以我建议你做这样的事情:
app.controller('MyCtrl', function($scope, $filter) {
$scope.blueprints = [ /* your data */ ];
$scope.currentPage = 0;
$scope.pageSize = 30;
$scope.groupSize = 3;
$scope.sortPty = 'stuff';
//load our filters
var orderBy = $filter('orderBy'),
startFrom = $filter('startFrom'),
limitTo = $filter('limitTo'),
group = $filter('group'); //from the filter above
//a method to apply the filters.
function updateBlueprintDisplay(blueprints) {
var result = orderBy(blueprints, $scope.sortPty);
result = startForm(result, $scope.currentPage * $scope.pageSize);
result = limitTo(result, $scope.pageSize);
result = group(result, 3);
$scope.blueprintDisplay = result;
}
//apply them to the initial value.
updateBlueprintDisplay();
//watch for changes.
$scope.$watch('blueprints', updateBlueprintDisplay);
});
然后在您的标记中:
<ul ng-repeat="grouping in blueprintDisplay">
<li ng-repeat="item in grouping">{{item}}</li>
</ul>
...我确定那里有错别字,但这是基本思想。
再次编辑:我知道您已经接受了这个答案,但是我最近了解到还有另一种方法,您可能会更喜欢:
<div ng-repeat="item in groupedItems = (items | group:3 | filter1 | filter2)">
<div ng-repeat="subitem in items.subitems">
{{subitem}}
</div>
</div>
这将在您的 $scope 上创建一个名为 $scope.groupedItems 的新属性,它应该有效地缓存您过滤和分组的结果。
试一试,让我知道它是否适合你。如果没有,我想其他答案可能会更好。