如何在范围内找到手表。$$观察者

时间:2014-03-11 16:46:42

标签: angularjs angularjs-directive angularjs-scope angularjs-ng-repeat ng-repeat

我使用angularjs并需要找到ng-repeat的手表,因为我需要ng-repeat停止从特定点开始工作。这是我的代码:

<ul>
  <li ng-repeat="item in items">
      <div>{{item.name}}</div>
  </li>
</ul>

我需要找到ng-repeat的观察者。如果我转到scope.$parent.$$watchers[x]并执行splice手表已被移除,但我该如何找到特定的手表?

5 个答案:

答案 0 :(得分:5)

无法找到手表(请参阅下面的说明),但您可以使用以下指令实现您的目标

app.directive('repeatStatic',
     function factory() {
      var directiveDefinitionObject = {
        restrict : 'A',
        scope : true, // this isolates the scope from the parent
        priority : 1001, // ng-repeat has 1000
        compile : function compile() {
          return {
            pre : function preLink(tElement, tAttrs) {
            },
            post : function postLink(scope, iElement, iAttrs, controller,
                transcludeFn) {
              scope.$apply(); // make the $watcher work at least once
              scope.$$watchers = null; // remove the $watchers
            },
          };
        }
      };

      return directiveDefinitionObject;
     }
    );

及其用法是

<ul>
  <li repeat-static ng-repeat="item in items">
    {{ item }}
  </li>
</ul>

请参阅http://plnkr.co/k9BTSk作为工作示例。

背后的理性是 angular指令 ng-repeat 指令使用内部函数$ watchCollection来添加一个自我创建的监听器,用于监视 items 对象。由于侦听器是在进程中创建的函数,并且不作为参考保留在任何位置,因此没有好的方法来正确识别要从$$观察者列表中删除的函数。

然而可以通过使用属性指令将新范围强制进入ng-repeat,这样,ng-repeat添加的$$观察者将与父范围隔离。因此,我们获得了对范围的完全控制。$$观察者。在ng-repeat使用填充值的函数后立即,可以安全地删除$$观察者。 该解决方案使用hassassin清理$$观察者列表的想法。

答案 1 :(得分:1)

我有一个Angular的分支,可以让你将手表放在$$watchers中,但大部分时间都会跳过它。与编写编译HTML的自定义指令不同,它允许您在内部使用普通的Angular模板,区别在于一旦内部完全呈现,手表将不再被检查。

除非你真的需要额外的表现,否则不要使用它,因为它可能会有令人惊讶的行为。

这是:

https://github.com/r3m0t/angular.js/tree/digest_limit

以下是您可以使用的指令(new-once):

https://gist.github.com/r3m0t/9271790

如果您希望页面永不更新,可以使用new-once=1,如果您希望有时更新,可以使用new-once=updateCount,然后在控制器中运行$scope.updateCount++;以触发更新

更多信息:https://github.com/Pasvaz/bindonce/issues/42#issuecomment-36354087

答案 2 :(得分:1)

我过去处理过这种情况的方式是我创建了一个自定义指令,它复制内置ngRepeat指令的逻辑,但从不设置监视。您可以看到此here的示例,该示例是从1.1.5版的ngRepeat代码创建的。

另一方面,正如您所提到的那样,将其从范围的$$watchers中删除,因为它访问私有变量,这有点陌生。

如何做到这一点就是你在重复上创建一个自定义指令来删除重复的手表。我创建了一个fiddle来做到这一点。它基本上只是在重复的最后一个元素清除父表(这是数据上的那个)

if (scope.$last) {
    // Parent should only be the ng-repeat parent with the main watch
    scope.$parent.$$watchers = null;
}

可以根据您的具体情况对其进行修改。

希望这有帮助!

答案 3 :(得分:0)

听起来您想将bindonce指令放在ng-repeat上。

https://github.com/Pasvaz/bindonce

答案 4 :(得分:0)

如果您不需要角度双重绑定,您是否尝试过具有complie函数的自定义指令,您可以通过从头创建DOM而不使用任何角度双绑定机制来自己构建HTML?