Angular什么时候清除$ watch?

时间:2014-11-09 15:59:55

标签: angularjs

据我所知,我在视图中包含的每个模型都会进入摘要循环并在其上应用$watch,因为所有Angular应用程序基本上都是一个页面应用程序。但什么时候清除$watch

例如,假设我的页面view1.html包含模板{{view.name1}}。当我使用模板view2.html将路线切换到页面{{view.name2}}时,$watch上的{{view.name1}}是否会自动取消注册,还是应该手动执行?

1 个答案:

答案 0 :(得分:8)

此答案包含angular scopes源代码

的链接

每个范围都有一个私有数组$$watchers

  • 调用方法$watch时,会将监听者推送到$$watchers,请参阅Scope#$watch
  • 每个$digest会迭代所有$$watchers,请参阅Scope#$digest
  • 当调用范围方法$destroy时,它会清除所有观察者,请参阅Scope#$destroy
  • 每个范围还会将$destroy广播到所有子范围内,无论是否隔离,因此您永远不会有孤儿范围。
  • Angular侦听DOM节点删除并触发$destroy所有指令范围(在$ compile服务中创建),请参阅here

Angular会在这些情况下自动调用$destroy


手动创建范围($destroy / $new)时,您只需要调用$transclude,并希望它们在父范围之前销毁。

ngView可能是一个很好的例子,因为你的应用程序中只有一个绑定到它的元素,并且该元素(通常是rootScope的范围)永远不会被销毁。因此,角度会在进入路径时自动创建一个新的子范围($new),并在存在时调用$destroy,从而冲洗由该路径创建的所有观察者。

来自Scope#$new docs

  当需要范围时,必须在范围上调用

$ destroy()   并且它的子范围永久地与父母分离   因此停止参与模型变化检测和监听   通过调用通知。

来自$compile - transclusion functions docs

  

如果您打算在您的手机中手动添加和删除已转换的内容   指令(通过调用transclude函数来获取DOM和   调用element.remove()删除它),那么你也有责任   在翻译范围内调用 $ destroy


以此为例,如果您手动创建了一个范围($new$transclude)并且不再需要它,但它是 父范围是否需要手动销毁它。