【问题标题】:Watching a deleted model?观看已删除的模型?
【发布时间】:2016-04-18 04:55:25
【问题描述】:

考虑这个伪代码:

$scope.model = [{ A: 'a', B: 'b' }, { A: 'c', B: 'd' }];

$scope.$watchCollection('model', (model) => {
  for (var i = 0; i < model.length; i += 1) {
    $scope.$watch('model[' + i + '].A', () => ...);
  }
});

如果我delete $scope.model[1],手表表达式会发生什么?是“内存泄漏”、僵尸还是其他泄漏?

编辑 这种方法为已经解决的问题提供了一个糟糕的解决方案。我最终使用 angularjs 相等检查而不是参考检查。请参阅 $watch 的文档。

【问题讨论】:

    标签: javascript angularjs angularjs-directive typescript


    【解决方案1】:

    $watch$watchcollection 在摘要周期内继续观察。如果感兴趣的项目再次被定义,$rootScope 将执行注册的侦听器函数。您可以通过调用注册$watch 时返回的注销函数来注销观察程序。 (您确实保存了它,不是吗?)

    var deRegisterFn = $scope.$watchCollection('model', function (newValue) {
          console.log(newValue);
    });
    
    delete $scope.model;
    deRegisterFn();
    

    否则,观察者会一直保留到作用域被销毁。

    有关$watch 的更多信息,请参阅AngularJS $rootScope.scope API Reference -- $watch

    顺便说一句,你的例子,在监听函数中添加观察者很奇怪。 AngularJS 不是 jQuery,甚至在 jQuery 社区中也有人反对绑定和取消绑定监听器。有些人甚至称其为反模式

    更新:objectEquality AKA Deep-Watch

    $watch(watchExpression, listener, [objectEquality]);

    • objectEquality == true 时,确定watchExpression 的不等式 根据angular.equals 函数。将对象的值保存为 稍后比较,使用angular.copy 函数。因此,这意味着 观看复杂的对象会对记忆和性能产生不利影响。

    出于性能原因,$watch 函数使用“浅层监视”。问题的作者需要对他的对象进行“深入观察”。由于不知道“objectEquality”选项,也称为(AKA)“deep watch”选项,他通过在模型的属性上添加和删除手表来解决他的问题。 “深度观察”选项以更简洁、更优雅的方式解决了他的问题。因此无需添加和删除手表。

    有关$watch 的更多信息,请参阅AngularJS $rootScope.scope API Reference -- $watch

    【讨论】:

    • 谢谢!我确实保存了观察者,所以我会确保调用该函数。
    • 之所以这样实现是因为我想在A更新时更新模型,或者集合发生变化。不使用监听器可以实现吗?
    • 您可以通过将第三个参数设置为true 来设置$watch 进行所谓的“深度观察”。 $scope.$watch("model", listenerFn, true);。有关详细信息,请参阅文档。
    • 谢谢你,@georgeawg! :) 我会看的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-22
    • 2018-12-16
    • 2020-11-18
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    相关资源
    最近更新 更多