发现问题

最近有客户投诉,说在删除指定的某条记录时,结果删掉的却是另外一条记录!看起来是个很严重的BUG。 有一次我们在工作中碰到了这个问题。 要定位这个BUG非常麻烦, 因为客户也不清楚如何重现这个问题。
后来发现这个Bug是由于在 ng-repeat 中使用了 $index 引发的。
一个简单动作(action)的列表
先来看看一个完整有效的ng-repeat示例。
<ul ng-controller="ListCtrl">
<li ng-repeat="item in items">
{{item.name}}
<button ng-click="remove($index)">remove</button>
</li>
</ul>
对应的控制器(controller)如下:
app.controller('ListCtrl', ['$scope', function($scope) {
//items come from somewhere, from where doesn't matter for this example
$scope.items = getItems();
$scope.remove = function(index) {
var item = $scope.items[index];
removeItem(item);
};
}]);
看起来没什么问题,对吗? 这段代码也没有任何特别值得注意的。
添加一个过滤器(filter)
然后,让我们来做一个小小的修改: 给列表添加一个过滤器。 这是很常见的做法,如果列表很长的话,例如允许用户进行搜索。
为了方便起见, 假设我们通过 searchFilter 来查询列表中的记录。
<ul ng-controller="ListCtrl">
<li ng-repeat="item in items | searchFilter">
{{item.name}}
<button ng-click="remove($index)">remove</button>
</li>
</ul>
控制器的代码保持不变。 看起来仍然没有问题,是吧?
事实上,有一个bug藏在里面。 如果我不说, 你能找到吗? 如果能找到,你就已经是Angular大牛了.
请尽量不要使用 $index
BUG其实是在控制器里面:
$scope.remove = function(index) {
var item = $scope.items[index];
removeItem(item);
};
这里使用了 index参数, 然后就遇到了BUG: 过滤后的索引(indexs)不匹配原始列表的索引。
幸运的是,有一个很简单的方法来避免这种问题: 不要使用$index,而改成实际的item对象。
<ul ng-controller="ListCtrl">
<li ng-repeat="item in items | searchFilter">
{{item.name}}
<button ng-click="remove(item)">remove</button>
</li>
</ul>
控制器如下所示:
$scope.remove = function(item) {
removeItem(item);
};
注意, 这里将 remove($index) 改成 remove(item) , 并修改了 $scope.remove 函数来直接操作传过来的对象。
这个小小的修改就完全避免了刚才的BUG。
为了更好地说明问题以及解决方案,请参考 interactive example 。
从中可以学到什么?
第一个教训当然是在使用 $index 要小心一点,因为以某些方式使用时很可能会产生BUG。
第二个教训是,请记住类似这样的模式,则可以用更好的做事方式,可以完全避免某些类型的BUG。 我强烈建议大家现在不要使用 $index, 从这种简单的思维转变中,就可以减少代码中的很多BUG。
第三个教训是测试并不是什么时候都有用。 即便有自动化测试,也覆盖了足够多的情形, 但对于依赖特定输入的情况,也很容易错过某些BUG。 错误本身并不是每次都会出现,即使你也用过滤来测试。
第四个教训是不要破坏抽象 —— 这一点很容易被忽略。理论上 $index 是由 ng-repeat 创建的一个 “模板变量(template variable)”。 这只在 repeat 块里面有意义(并正确起作用)。 当我们将它的值传递到外面时,它就失去了上下文从而不再有效。 如果确实想让它在 repeat 之外依然有效,则必须在控制器中也进行过滤,这就需要一些不是很必要的重复代码。 值得庆幸的是本文中介绍的模式可以用来避免这种情况。
结束语
以上就是关于AngularJS实践之ng-repeat中$index使用注意事项的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
原文链接: AngularJS best practices: Be careful when using ng-repeat's $index
原文日期: 2014-11-10
翻译日期: 2015-01-23
翻译人员: 铁锚 http://blog.csdn.net/renfufei
# ng
# repeat
# index
# angularjs中ng
# 嵌套
# AngularJs ng-repeat 嵌套如何获取外层$index
# AngularJS入门(用ng-repeat指令实现循环输出
# AngularJS 获取ng-repeat动态生成的ng-model值实例详解
# AngularJS ng-repeat数组有重复值的解决方法
# angularjs在ng-repeat中使用ng-model遇到的问题
# Angularjs的ng-repeat中去除重复数据的方法
# AngularJS使用ng-repeat指令实现下拉框
# Angularjs中ng-repeat的简单实例
# 的是
# 是在
# 这个问题
# 有一个
# 铁锚
# 这是
# 是个
# 使用了
# 也不
# 第一个
# 你就
# 却是
# 让我们
# 也没
# 什么时候
# 是由
# 很容易
# 这段
# 你能
# 这就
相关文章:
如何通过FTP服务器快速搭建网站?
如何通过老薛主机一键快速建站?
建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略
如何在阿里云香港服务器快速搭建网站?
专业公司网站制作公司,用什么语言做企业网站比较好?
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
番禺网站制作公司哪家值得合作,番禺图书馆新馆开放了吗?
电商平台网站制作流程,电商网站如何制作?
建站VPS选购需注意哪些关键参数?
建站之星2.7模板快速切换与批量管理功能操作指南
高端智能建站公司优选:品牌定制与SEO优化一站式服务
网站制作公司,橙子建站是合法的吗?
,南京靠谱的征婚网站?
测试制作网站有哪些,测试性取向的权威测试或者网站?
建站之星收费标准详解:套餐费用及年费价格表一览
如何设置并定期更换建站之星安全管理员密码?
网站制作壁纸教程视频,电脑壁纸网站?
如何通过虚拟机搭建网站?详细步骤解析
网站制作话术技巧,网站推广做的好怎么话术?
成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?
一键制作网站软件下载安装,一键自动采集网页文档制作步骤?
如何通过多用户协作模板快速搭建高效企业网站?
唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?
建站之星如何助力网站排名飙升?揭秘高效技巧
如何使用Golang table-driven基准测试_多组数据测量函数效率
宁波免费建站如何选择可靠模板与平台?
如何高效配置IIS服务器搭建网站?
制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?
网站制作软件有哪些,制图软件有哪些?
如何通过西部数码建站助手快速创建专业网站?
行程制作网站有哪些,第三方机票电子行程单怎么开?
如何用好域名打造高点击率的自主建站?
网站制作难吗安全吗,做一个网站需要多久时间?
建站之星安装失败:服务器环境不兼容?
如何选择适配移动端的WAP自助建站平台?
历史网站制作软件,华为如何找回被删除的网站?
阿里云网站制作公司,阿里云快速搭建网站好用吗?
IOS倒计时设置UIButton标题title的抖动问题
企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?
想学网站制作怎么学,建立一个网站要花费多少?
平台云上自主建站:模板化设计与智能工具打造高效网站
如何在景安服务器上快速搭建个人网站?
建站之星logo尺寸如何设置最合适?
存储型VPS适合搭建中小型网站吗?
深圳网站制作案例,网页的相关名词有哪些?
如何在IIS中新建站点并解决端口绑定冲突?
如何选择高效响应式自助建站源码系统?
如何选择高效稳定的ISP建站解决方案?
如何通过二级域名建站提升品牌影响力?
*请认真填写需求信息,我们会在24小时内与您取得联系。