JVG*_*JVG 36 angularjs angularjs-ng-repeat angularjs-filter
我有一个简单的<input>
搜索过滤器设置为项目名称列表AngularJS
.
我的列表看起来像这样:
var uniqueLists = {
category1: ['item1', 'item2', 'item3' ... 'item180' ], // Real list contains ~180 items
category2: ['itemA', 'itemB', 'itemC' ... 'itemZZZ' ], // Real list contains ~1080 items
category3: ['otheritem1', 'otheritem2', 'otheritem3' ] // Real list contains 6 items
}
Run Code Online (Sandbox Code Playgroud)
我在Angular中遍历此列表并在<ul>
每个类别中打印出结果.
<div ng-repeat="(key,val) in uniqueLists">
<form ng-model="uniqueLists[index][0]">
<input ng-model="searchFilter" type="text" />
<ul>
<li ng-repeat="value in val | filter: searchFilter">
<label>
<input type="checkbox" ng-model="selectedData[key][value]" />
{{value}}
</label>
</li>
</ul>
</form>
</div>
Run Code Online (Sandbox Code Playgroud)
为清楚起见,selectedData如下所示:
var selectedData = {category1: [item1:true], category2: [], category3: []); // if 'item1's checkbox is checked.
Run Code Online (Sandbox Code Playgroud)
这个列表运行得很好,虽然filter
它非常滞后,即使在我非常快的计算机上也是如此.在输入中键入一个字母需要1-2秒才能更新列表.
我知道这可能是因为我一次过滤大约1000件物品,但我没有在其他地方看到过这方面的任何讨论.
有没有办法从过滤器中获得更好的性能?
Yos*_*shi 55
滤波器方法的主要问题是每次更改时都会操纵dom,因此滤波器不是缓慢但后果.另一种方法是使用类似的东西:
ng-show="([item] | filter:searchFilter).length > 0"
Run Code Online (Sandbox Code Playgroud)
关于重复的元素.
从@OverZealous借出一些代码,您可以使用以下内容来比较行为:
更新:使用Angular v1.2来了track by
语法.这也有助于解决这些问题.如果元素具有一些唯一属性,则可以使用:
ng-repeat="item in items | filter:searchFilter track by item.id"
Run Code Online (Sandbox Code Playgroud)
当item.id
必须跨越所有项目唯一的.与track by
只有那些以DOM元素将被移除这已经不再是在最后的名单,其他人将被铭记.而没有track by
整个列表每次都重新绘制.简而言之:更少的dom操作=更快的重绘.
Tyv*_*ain 21
另一个有趣的优化是在一定时间之前"不触发"模型更改.
将其添加到您的搜索输入字段:ng-model-options ="{debounce:500}"
如果用户在500ms内停止输入,则会触发过滤器.
我更新了上面的小提琴:
<input ng-model="searchFilter" type="text" ng-model-options="{debounce: 500}" />
Run Code Online (Sandbox Code Playgroud)
在我的计算机上,这是快速但不是超快,运行良好.它有点慢,但它过滤了一个过长的列表,它与复选框有双向绑定.每次键入字母时,都必须扫描整个列表并删除(或添加)项目.
我认为解决这个问题最好的办法是添加一些简单的分页,如StackOverflow的答案所示.
在这里,我修改了我的例子以包括分页.您可能希望投资一个比下一个/上一个更好的解决方案,但这会向您展示如果您不是一次性显示所有内容,结果会如何非常快.它仍然搜索整个列表,但渲染列表更加有限.
增加:
将分页信息添加到控制器中的范围:
$scope.currentPage = 0;
$scope.pageSize = 20;
$scope.numberOfPages = function () {
return Math.ceil($scope.items.length / $scope.pageSize);
}
Run Code Online (Sandbox Code Playgroud)
创建一个从特定页面开始的新过滤器:
app.filter('startFrom', function () {
return function (input, start, pageSize) {
start = +start; //parse to int
pageSize = +pageSize;
while (start > input.length) {
start -= pageSize;
}
if (start < 0) {
start = 0;
}
return input.slice(start);
};
});
Run Code Online (Sandbox Code Playgroud)
向视图添加过滤器以限制列表:
<li ng-repeat="value in items | filter:searchFilter |
startFrom:currentPage*pageSize:pageSize | limitTo:pageSize">
Run Code Online (Sandbox Code Playgroud)
将分页按钮添加到页面:
<div>
<button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1">Previous</button> {{ currentPage+1 }}/{{ numberOfPages() }}
<button ng-disabled="currentPage >= items.length/pageSize - 1" ng-click="currentPage=currentPage+1">Next</button>
</div>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
21965 次 |
最近记录: |