假设我有一个大阵列的ng-repeat.
当ng-repeat运行时,它会将该数组的每个元素添加到隔离范围,并将数组本身放在范围内.这意味着$ digest会检查整个数组是否有变化,最重要的是,它会检查该数组中的每个元素是否有变化.
看到这个plunker作为我正在谈论的一个例子.
在我的用例中,我从不更改数组中的单个元素,因此我不需要让它们被观看.我只会更改整个数组,在这种情况下,ng-repeat会重新整理表格.(如果我错了,请告诉我..)
在一个(比方说)1000行的数组中,这是我不需要评估的1000多个表达式.
如何在观看主阵列时从观察者中取消注册每个元素?
也许不是取消注册我可以更好地控制我的$ digest并以某种方式跳过每一行?
这个具体案例实际上是一个更普遍的问题的例子.我知道$ watch会返回一个'deregisteration'函数,但是当指令正在注册监视时这没有用,这在大多数情况下都是如此.
Ben*_*esh 89
要有一个大型阵列的转发器,您不会观看每个项目.
你需要创建一个自定义指令,它接受一个参数,表达式到你的数组,然后在你刚刚看到那个数组的链接函数中,你就可以通过编程方式刷新HTML(而不是使用一个NG-重复)
像(伪代码):
app.directive('leanRepeat', function() {
return {
restrict: 'E',
scope: {
'data' : '='
},
link: function(scope, elem, attr) {
scope.$watch('data', function(value) {
elem.empty(); //assuming jquery here.
angular.forEach(scope.data, function(d) {
//write it however you're going to write it out here.
elem.append('<div>' + d + '</div>');
});
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
......这似乎是一个痛苦的屁股.
替代的hackish方法
您可以循环$scope.$$watchers检查$scope.$$watchers[0].exp.exp以查看它是否与您要删除的表达式匹配,然后通过简单的splice()调用将其删除.这里的PITA是Blah {{whatever}} Blah标签之间的东西将是表达式,甚至包括回车.
从好的方面来说,你可能只需循环遍历ng-repeat的$ scope并删除所有内容,然后明确添加你想要的手表......我不知道.
无论哪种方式,它似乎是一个黑客.
删除由$ scope.$ watch制作的观察者
您可以$watch使用调用返回的函数取消注册a $watch:
例如,$watch只有一次火:
var unregister = $scope.$watch('whatever', function(){
alert('once!');
unregister();
});
Run Code Online (Sandbox Code Playgroud)
当然,您可以随时调用取消注册功能......这只是一个例子.
结论:没有一个很好的方法可以完全按照你的要求去做
但有一点需要考虑:它是否值得担心?此外,将数千条记录分别加载到数十个DOMElements中真的是一个好主意吗?值得深思.
我希望有所帮助.
编辑2(删除坏主意)
ood*_*vid 15
$ watch返回一个函数,在调用时取消绑定$ watch.所以这就是"watchOnce"所需要的:
var unwatchValue = scope.$watch('value', function(newValue, oldValue) {
// Do your thing
unwatchValue();
});
Run Code Online (Sandbox Code Playgroud)
编辑:看到我发布的其他答案.
我已经离开并以可分离的方式实施了肉体的想法.我的ngOnce指令只会破坏ngRepeat在每个项目上创建的子范围.这意味着范围无法从其父母那里到达,scope.$digest并且观察者从未被执行过.
指令本身:
angular.module('transclude', [])
.directive('ngOnce', ['$timeout', function($timeout){
return {
restrict: 'EA',
priority: 500,
transclude: true,
template: '<div ng-transclude></div>',
compile: function (tElement, tAttrs, transclude) {
return function postLink(scope, iElement, iAttrs, controller) {
$timeout(scope.$destroy.bind(scope), 0);
}
}
};
}]);
Run Code Online (Sandbox Code Playgroud)
使用它:
<li ng-repeat="item in contents" ng-once>
{{item.title}}: {{item.text}}
</li>
Run Code Online (Sandbox Code Playgroud)
注意 ng-once不会创建自己的范围,这意味着它可以影响兄弟元素.这些都做同样的事情:
<li ng-repeat="item in contents" ng-once>
{{item.title}}: {{item.text}}
</li>
<li ng-repeat="item in contents">
<ng-once>
{{item.title}}: {{item.text}}
</ng-once>
</li>
<li ng-repeat="item in contents">
{{item.title}}: {{item.text}} <ng-once></ng-once>
</li>
Run Code Online (Sandbox Code Playgroud)
请注意, 这可能是一个坏主意
| 归档时间: |
|
| 查看次数: |
42108 次 |
| 最近记录: |