观看已删除的模型?

Posted

技术标签:

【中文标题】观看已删除的模型?【英文标题】: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 的文档。

【问题讨论】:

【参考方案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! :) 我会看的!

以上是关于观看已删除的模型?的主要内容,如果未能解决你的问题,请参考以下文章

从服务器删除已发送的推送通知

Laravel 的模型之一未调用已删除的方法

109 - 删除一个模型

Forge 数据管理搜索 api 是不是返回任何数据以指示模型已被删除?

使用 Magical Record 迁移核心数据失败并显示“已删除不兼容的模型版本”

已审核的 gem 未审核删除关系