【问题标题】:angularjs ngRepeat directive to not trigger digest for other items in the listangularjs ngRepeat 指令不触发列表中其他项目的摘要
【发布时间】:2014-05-09 12:54:07
【问题描述】:

似乎 ngRepeat 在更改其中一个后触发了任何列表项上的监视。我已经在使用 track by 所以这似乎没有帮助。

这是我的模板:

div(ng-repeat="poll in polls track by poll._id")
  poll(poll="poll")

.poll
  .title(ng-if="!poll.closed") {{poll.title}}
  .btn(ng-click="poll.closed = true") Change poll
  {{someExpensiveComputation(poll._id)}}

javascript:

.directive('poll', function($rootScope, $modal) {
  return {
    replace: false,
    restrict: 'E',
    scope: {
      poll: '='
    },
    templateUrl: '/tmpl/poll',
    link: function($scope, elem, attrs) {
      $scope.someExpensiveComputation = function (id) { ... }
    }
  }
});

似乎每当更改投票项目时, someExpensiveComputation 函数都会针对所有投票运行,并且每次运行 3 次。我怎样才能让它不这样做?它应该只触发该指令的观察者。我认为这应该是可能的。

谢谢。

【问题讨论】:

  • 民意调查有何变化?谁改的?
  • @ExpertSystem 嗨,谢谢。我用投票编辑的例子编辑了这个问题。

标签: javascript angularjs angularjs-directive


【解决方案1】:

所有watch-表达式在每个 $digest 循环中都会被多次处理(评估)。
因此,最好让 watch 表达式尽可能简单(就计算复杂性而言)。

(顺便说一句,在您的视图中使用{{...}} 会创建一个watch。)

如果someExpensiveComputation() 是...计算成本很高,您不想每次都评估它,但只在它可能产生不同结果时进行评估。这取决于函数的实现,但假设其结果仅依赖于每个轮询的属性,那么您可以 watch 轮询并在其更改时调用昂贵的函数:

.poll
...
{{expensivelyComputedValue}}

.directive('poll', function($rootScope, $modal) {
    return {
        ...
        link: function(scope, elem, attrs) {
            function someExpensiveComputation(id) { ... }

            scope.expensivelyComputedValue = someExpensiveComputation(scope.poll.id);
            scope.$watch('poll', function (newValue, oldValue) {
                if (newValue === oldValue) { return; }
                scope.expensivelyComputedValue = someExpensiveComputation(scope.poll.id);
            }, true);
        }
    }
});

当然,如果昂贵的计算结果只依赖于 poll 的一个特定属性(而不是整个对象),那么只需要 watch 这个属性就足够了,从而保持你的 watch-表达式更加“轻量级”。例如:

scope.$watch('poll.closed', function (...) {...});

【讨论】:

  • 谢谢 有没有办法通过使用模板而不是在控制器中手动观看来获得这种行为?对更高范围的更改没有反应的本地观察者?
  • 恐怕没有这样的远方。如果您确定数据只会在您按下按钮时发生变化,您可以将对 someExpensiveComputation() 的调用合并到按钮单击处理程序中。
  • 哇!反对票有什么用?我的随附评论在哪里?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-17
  • 2014-06-01
  • 2016-05-20
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多