angularjs中使用ng-repeat的注意点
2018-01-16 11:10
507 查看
1、ng-repeat的数据不能出现重复项问题
通常情况下,ng-repeat的数据是不可以重复的,否则就会报错。原因是angular需要一个唯一值可以与生成的dom绑定,以便追踪.解决方案: <div ng-repeat="(key,value) in datas track by key"></div>
2、ng-repeat的性能问题
AngularJs 的 ng-repeat 让我们非常方便的遍历数组/对象来生成 Dom 元素,然后在使用过程中也需要注意性能问题。原理:在项目中我们使用 ng-repeat 加载完一个列表后,如果再次请求数据,当 ng-repeat 的数组被替换时, 它默认并不会重新利用已有的 Dom 元素,而是直接将其全部删除并重新生成新的数组 Dom 元素。而频繁的操作dom显然是很不友好的。为什么 ng-repeat 不能利用已有的 dom 元素去更新数据呢?因为你没有把数组元素的标识属性告诉它,那么两次替换的时候它就没办法追踪了。我们可以看到 ng-repeat 往数组里每个元素加了一个 $$hashKey 的属性:
这个 key 是由 Angular 内部的 nextUid() 方法生成,类似数据库自增,但是是使用字符串。
现在我们明白了,因为每次替换数组都会导致 ng-repeat 为每个元素生成一个新 key, 所以根本没办法重用已有的 Dom 元素,那么我们可以使用下边的语法来避免这个问题:
<div ng-controller="Test"> <button ng-click="request()">请求新数据</button> // 使用 track by 标识 <div ng-repeat="user in users track by user.id"> {{user.name}} </div> </div>
这样 ng-repeat 就用将其缓存起来啦,当然可能你的数组元素没有一个标识属性,如果元素数量不多那么可以接受,不然还是建议你手动为其生成一个标识属性,类似于id。
3、ng-options遇到的问题
ng-options的使用原理和ng-repeat 是一致的,都可以很方便的遍历数组/对象。先来看一组代码:$scope.selectDatas = [ { id: "1", name: "apple" }, { id: "2", name: "origin" }, { id: "3", name: "bananer" },{ id:"4", name:"pear" }];
html中展示: <select ng-change="editChangeSelectDatas()" ng-options="obj.name for obj in selectDatas" ></select>
这样就可以将下拉列表完美的展示出来了。当我们想下拉列表默认选中一个时,代码如下:
$scope.selectDataSelected = {name:"pear",id:"4"};
<select ng-change="editChangeSelectDatas()" ng-options="obj.name for obj in selectDatas" ng-model="selectDataSelected"></select>
此时,默认选中pear,非常完美!然而当我在去变换选择其他项时,会发现下拉列表始终展示的是我默认设置为显示的那一项,what should i do?
原因:ng-repeat指令为集合中的每项都实例化一个模块。每个模块都有自己的scope,也就是说ng-model绑定的selectDataSelected的作用域已经发生变化,你在通过ng-repeat去设置scope.selectDataSelected=scope.selectDatas[i],是无效的。因为每一个$scope.selectDataSelected都有自己的作用域。
解决方案:
$scope.obj = {selectDataSelected :{name:"pear",id:"4"}}
<select ng-change="editChangeSelectDatas()" ng-options="obj.name for obj in selectDatas" ng-model="obj.selectDataSelected"></select>
这样他始终绑定的都是obj对象下的selectDataSelected,就可以避免类似的问题了。
另外使用ng-model双向绑定的时候,建议去绑定他的对象属性比如ng-model=”obj.name”,而不是ng-model=”name”,这样可避免出现此类问题。
4、ng-repeat如何在渲染完成后再去执行脚本
ng-repeat遍历渲染完页面后如何去执行某个操作??接下来需要我们了解一下ng-repeat循环中的几个特殊变量。变量 | 类型 | 描述 |
---|---|---|
$index | number | 当前索引。 |
$first | boolean | 当循环的对象存在第一项时为true。 |
$middle | boolean | 当循环的对象存在中间项时为true。 |
$last | boolean | 当循环对象存在最后一项时为true。 |
$even | boolean | 循环的对象在当前位置的索引是偶数则为true。 |
$odd | boolean | 循环的对象在当前位置的索引是奇数则为true。 |
<div id="box"> <span ng-repeat="item in data" repeat-finish="renderFinish()">{{item.str}}</span> </div>
app.directive('repeatFinish',function(){ return { link: function(scope,element,attr){ console.log(scope.$index); //也可使用scope.$watch('$last',function(){}); if(scope.$last == true){ console.log('ng-repeat执行完毕') scope.$eval( attr.repeatFinish ) } } } }) //controller里对应的处理函数 $scope.renderFinish = function(){ console.log('渲染完之后的操作') }
总结:在第一个和第二个问题中反复用到了track by来解决问题,简单了解一下,angular需要一个唯一值可以与生成的dom绑定,以便追踪,因此track by 后面跟的值一定是唯一的,如果一旦出现重复数据,均会保错(包括如果track by 后面的值为undefined,多个undefined也同样会报错),而orderby是可以出现重复数据的,orderby和track by一起使用的格式为:
<tr ng-repeat="item in $ctrl.indicators | orderBy:'id' track by item._id">
提高性能的同时,进行排序。
相关文章推荐
- angularjs中使用ng-repeat需要注意的东西
- AngularJS实践之使用ng-repeat中$index的注意点
- 【AngularJS】使用ng-repeat中$index的注意点
- 使用angularjs中ng-repeat的$even与$odd属性时的注意事项
- Angularjs使用ng-repeat中$even和$odd属性的注意事项
- AngularJS中,联合使用ng-repeat和ng-if,可以实现对数据删选显示效果,特别适合于用作表单数据的显示
- [Angularjs]ng-repeat中使用ng-model遇到的问题
- AngularJS使用 ng-repeat 中的 $index与替代方法
- AngularJS使用自定义指令替代ng-repeat的方法
- AngularJs 在ng-repeat中动态使用ng-model进行双向数据绑定
- AngularJS最佳实践: 请小心使用 ng-repeat 中的 $index
- AngularJS最佳实践: 请小心使用 ng-repeat 中的 $index
- angularjs中使用ng-repeat渲染最后一个li的时候设置不同样式
- AngularJS中ng-repeat使用心得
- AngularJS:如何使用自定义指令来取代ng-repeat
- AngularJS:如何使用自定义指令来取代ng-repeat
- angularjs在ng-repeat中使用ng-model遇到的问题
- 【Angularjs】ng-repeat中使用ng-model遇到的问题
- angularjs中ng-repeat里面ng-model的使用
- 解决angularjs 使用 ng-repeat 循环输出时html元素无法解析的问题