一尘不染

如何“取消监视”表达式

angularjs

说我有一个大阵列的ng-repeat。

ng-repeat运行时,它将数组的每个元素添加到隔离的作用域中,并将数组本身包含在作用域中。这意味着$
digest会检查整个数组是否有更改,最重要的是,它会检查该数组中的 每个单独元素 是否有更改。

看到这个傻瓜是我在说什么的例子。

在我的用例中,我永远不会更改数组的单个元素,因此不需要监视它们。我只会更改整个数组,在这种情况下ng-
repeat会重新呈现整个表。(如果我对此有误,请告诉我。)

在(例如)1000行的数组中,那是我不需要再计算的1000个表达式。

如何在仍然监视主数组的同时从观察者注销每个元素?

也许不用注销,我可以更好地控制$ digest并以某种方式跳过每一行?

实际上,这种特定情况是更普遍问题的一个示例。我知道$
watch返回一个’deregisteration’函数
,但这在大多数情况下在指令注册手表时没有帮助。


阅读 218

收藏
2020-07-04

共1个答案

一尘不染

要拥有一个大阵列的中继器,您不必看就可以观看每个项目。

您需要创建一个自定义指令,该指令需要一个参数和表达式到您的数组,然后在链接函数中只需观察该数组,然后让链接函数以编程方式刷新HTML(而不是使用ng-
repeat)

类似于(伪代码):

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>');
              });
           });
        }
    };
});

…这似乎是一种痛苦。

替代骇客方法

您也许可以循环浏览$scope.$$watchers并检查$scope.$$watchers[0].exp.exp它是否与您要删除的表达式匹配,然后通过一个简单的splice()调用将其删除。这里的PITA是Blah {{whatever}} Blah标记之间的东西将是表达式,甚至包括回车符。

从好的方面来说,您也许可以通过ng-repeat的$ scope循环并删除所有内容,然后显式添加所需的手表……我不知道。

无论哪种方式,似乎都像是骇客。

删除$ scope制造的观察者。

您可以$watch使用调用返回的功能注销a $watch

例如,一次$watch只能开火:

var unregister = $scope.$watch('whatever', function(){ 
     alert('once!');
     unregister();
});

当然,您可以随时调用unregister函数……这只是一个例子。

结论:确实没有一种很好的方法可以完全满足您的要求

但是要考虑的一件事:甚至值得担心吗?此外,将数千个记录加载到数十个DOMElement中真的是一个好主意吗?值得深思。

希望对您有所帮助。


编辑2(删除坏主意)

2020-07-04