我已经知道了如何处理ng-repeat性能问题(与观察者一起)的常见模式,如:一次性绑定,无限滚动等.
但我看到这个answer的人建议转向指令.
好的,我开始采用简单的旧方法
这个html有100个项目:
<div ng-repeat="e in ct.arr">
<div class='s'>
<span >name:{{e.name}} , age:{{e.age}} , height:{{e.height}}</span>
<hr>
</div>
这将产生301个观察者,当我点击一个按钮时我可以更改第5个项目:
那么我想把它移到指令(就像建议的那样):
现在HTML是:
<div ng-repeat="e in ct.arr">
<div class='s'>
<span my-event="e" ></span>
<hr>
</div>
</div>
指令:
.directive('myEvent', function() {
return {
scope: {
event: "=myEvent"
},
link: link,
}
function link(scope, element, attrs) {
var ev = scope.event;
element.text('name:'+ev.name +', age:'+ev.age+' , height:'+ev.height)
}
});
现在我只有101名观察者,但现在按钮没有影响:
问题:
>如果我是对的,100名观察者是因为孤立范围的直接别名是通过’=’.但如果它是该项目的直接别名,为什么我没有看到按钮点击后的修改?
>如果我想看到修改,我是否被301观察员困扰?还有什么我没有想到的 – 可以做到吗?
最佳答案 像Alainlb写的那样,你只是在创建时计算内容一次.当然就像你在评论中写一样,使用模板:’< span>名称:{{event.name}},年龄:{{event.age}},身高:{{event.height}}< ; /跨度>”添加手表(每个{{…}}是幕后的手表).
想到的第一个解决方案是使用监视指令的项目.深度监视具体,以便它可以检测对象属性的更改,而不仅仅是对实际对象引用的更改:
function link(scope, element, attrs) {
scope.$watch('event', function(ev) {
element.text('name:' + ev.name + ', age:' + ev.age + ' , height:' + ev.height);
}, true);
}
http://plnkr.co/edit/marpxMx5qin7mOlFwp3X?p=preview
分数:201手表
但我们可以做得更好;因为我们正在手动观察,所以= scope绑定现在是多余的.哦,然后范围:{}配置为空;我们甚至可以没有范围,既不是孤立的,也不是新的原型继承的.让我们使用scope:false(每次迭代可以节省1个范围对象,对于许多迭代来说都是很好的增益).
我们现在直接观察my-event属性中给出的表达式:
.directive('myEvent', function() {
return {
scope: false,
link: link,
};
function link(scope, element, attrs) {
scope.$watch(
attrs.myEvent,
function(ev) {
element.text('name:' + ev.name + ', age:' + ev.age + ' , height:' + ev.height);
},
true
);
}
});
http://plnkr.co/edit/lvnIQCJMnniFlOeRseaZ?p=preview
分数:101手表
有一个问题:深度观察产生较少的手表,但它们更昂贵,因为它们迭代观察对象的每个属性.因此,真正的性能提升可能会低于它看起来的效果 – 101手表对301手表.我们可以做得更好吗?
在尝试之前,我首先要测量101深表和301表之间的真正性能差异.如果可以忽略不计,我们没关系.否则,我们可能会使用Javascript属性getter和setter在我们的更新中变得“更聪明”,并且可能在对象上手动设置脏标志.这将很复杂.
更好的方法是永远不要改变对象的内部属性(将其视为不可变 – 一般来说是一个好主意)并更改引用本身.即做:
vm.c10 = function (){
this.arr[4] = {
name: "aaaa",
age: "aaaa",
height: "aaaa"
};
};
然后你不再需要深入观察(从范围的参数中删除,true.$watch).如果你可以强制执行对象是不可变的约定(Immutable.js任何人?),你是独自工作,或者团队(现在和将来)与这个约定有良好的沟通和理解,那么这种方法效果最好.否则就会出现邪恶的错误.