首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何“取消监视”表达式

如何“取消监视”表达式
EN

Stack Overflow用户
提问于 2012-12-01 03:12:27
回答 5查看 43.4K关注 0票数 70

假设我有一个带有一个大数组的ng-repeat。

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

this plunker作为我正在讨论的一个示例。

在我的用例中,我从不更改数组的任何一个元素,所以我不需要监视它们。我将只更改整个数组,在这种情况下,ng-repeat将重新呈现整个表。(如果我说错了,请告诉我。)

在(比方说) 1000行的数组中,我不需要计算的表达式又多了1000个。

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

也许我可以更多地控制我的$digest,并以某种方式跳过每一行,而不是取消注册?

这个特定的案例实际上是一个更普遍的问题的例子。我知道$watch returns a 'deregisteration' function,但在大多数情况下,当指令注册手表时,这并不起作用。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-12-01 03:53:01

有一个大阵列的中继器,你并不是为了观看每一个项目而观看的。

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

类似于(psuedo-code):

代码语言:javascript
复制
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()调用删除它。这里的要点是,像标记之间的Blah {{whatever}} Blah这样的东西将是表达式,甚至还将包括回车。

从好的方面来说,你也许能够循环通过你的ng- $scope,删除所有的东西,然后显式地添加你想要的监视……我不知道。

不管怎样,这看起来像是一次黑客攻击。

删除由$scope.$watch制作的监视器的

您可以使用$watch调用返回的函数注销$watch

例如,要使$watch只触发一次:

代码语言:javascript
复制
var unregister = $scope.$watch('whatever', function(){ 
     alert('once!');
     unregister();
});

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

结论:没有一种很好的方法可以完全按照的要求去做

但有一件事需要考虑:这值得担心吗?此外,将数以千计的记录加载到几十个DOMElements中真的是一个好主意吗?发人深省。

我希望这能有所帮助。

EDIT 2(删除坏主意)

票数 89
EN

Stack Overflow用户

发布于 2016-02-23 02:07:50

$watch返回一个函数,该函数在被调用时解除绑定$watch。所以这就是“watchOnce”所需要的:

代码语言:javascript
复制
var unwatchValue = scope.$watch('value', function(newValue, oldValue) {
  // Do your thing
  unwatchValue();
});
票数 16
EN

Stack Overflow用户

发布于 2013-06-28 20:16:54

编辑:查看我发布的另一个答案。

我已经以一种可分离的方式实现了blesh的想法。我的ngOnce指令只是销毁了ngRepeat在每个项目上创建的子范围。这意味着作用域不能从其父对象的scope.$digest访问,并且监视器永远不会被执行。

Source and example on JSFiddle

指令本身:

代码语言:javascript
复制
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);
            }
        }
    };
}]);

使用它:

代码语言:javascript
复制
      <li ng-repeat="item in contents" ng-once>
          {{item.title}}: {{item.text}}
      </li>

Note ng-once不会创建自己的作用域,这意味着它会影响同级元素。它们做的都是一样的事情:

代码语言:javascript
复制
  <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>

备注 this may be a bad idea

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13651578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档