我正在尝试确定当范围销毁时,角度基数是否会自动取消绑定与$scope.$on(...)
或$scope.$watch(...)
绑定的观察者和范围事件?
假设我有以下代码:
$scope.$on('someEvents', handleSomeEvent);
$scope.$watch('someProperty', handleSomePropertyChange);
在范围内触发$ destroy事件时,是否需要手动取消绑定这些观察者和事件?
答案 0 :(得分:30)
根据Angular documentation on $scope
:
当需要将作用域及其子作用域与父作用域永久分离并因此通过调用停止参与模型更改检测和侦听器通知时,必须在作用域上调用$ destroy()'。
另外
删除还意味着当前范围符合垃圾回收的条件。
因此,当$destroy()
被调用时,所有观察者和听众都被删除,而代表范围的对象变为eligible for garbage collection
。
如果我们查看destroy()
source code,我们会看到一行:
forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
应该删除所有侦听器。
如@glepretre所述,它适用于控制器中的观察者和监听者。上面列出的相同文档页面表示:
请注意,在AngularJS中,还有一个$ destroy jQuery事件,可以在从DOM中删除元素之前清除DOM绑定。
因此,如果指令中有特定的侦听器,您应该听取$destroy
事件并自行进行必要的清理
答案 1 :(得分:11)
如果示波器在控制器中,则为您取消角度取消绑定。否则,您可以通过调用返回的函数来取消绑定事件:
var myevent = $scope.$on('someEvents', handleSomeEvent);
myevent() ; // unbind the event
答案 2 :(得分:5)
如前所述,Angular确实会尽可能地为您清理物品。因此,如果您执行$scope.$on('someEvents', handleSomeEvent);
,一旦范围被销毁(例如,当您转到应用中的其他页面/视图时),该事件将自动删除。
值得注意的一点是,除非您退出应用,否则$rootScope
当然永远不会被销毁。因此,如果您执行$rootScope.$on('someEvents', handleSomeEvent);
,则可能必须自行删除活动,具体取决于您在何处收听活动:
controller
或directive
中,则您必须手动删除它,否则每次您实例化controller
时,都会附加一个新事件,并且所以handleSomeEvent
会被多次调用service
中,则您无需手动删除,因为服务始终为singleton
(请注意,在Angular service
中,factory
,...最终都是同样的事情)