angular.js $ destroy事件 - 我应该手动取消绑定吗?

Vyt*_*kus 35 javascript angularjs angularjs-scope

我试图弄清楚角度基数是否会自动解除观察者和范围事件的约束,$scope.$on(...)或者$scope.$watch(...)当范围被破坏时

假设我有以下代码:

$scope.$on('someEvents', handleSomeEvent);
$scope.$watch('someProperty', handleSomePropertyChange);
Run Code Online (Sandbox Code Playgroud)

在范围内触发$ destroy事件时,是否需要手动取消绑定这些观察者和事件?

Igo*_*lyk 30

根据Angular文档$scope:

当需要将范围及其子范围与父级永久分离并因此通过调用停止参与模型更改检测和侦听器通知时,必须在范围上调用'$ destroy()'.

删除还意味着当前范围符合垃圾收集的条件.

因此,当$destroy()调用时,所有观察者和听众都被移除,并且代表范围的对象变为eligible for garbage collection.

如果我们查看destroy() 源代码,我们会看到一行:

forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
Run Code Online (Sandbox Code Playgroud)

应该删除所有的听众.

正如@glepretre所提到的,它适用于控制器中的观察者和监听者.上面列出的相同文档页面表示:

请注意,在AngularJS中,还有一个$ destroy jQuery事件,可以在从DOM中删除元素之前清除DOM绑定.

因此,如果您在指令中有特定的侦听器,您应该听取$destroy事件并自己进行必要的清理


Max*_*dow 11

如果示波器在控制器中,则角度取消绑定.否则,您可以通过调用返回的函数来取消绑定事件:

var myevent = $scope.$on('someEvents', handleSomeEvent);
myevent() ; // unbind the event
Run Code Online (Sandbox Code Playgroud)

http://docs.angularjs.org/api/ng/function/angular.bind


use*_*648 5

如前所述,Angular确实会尽可能为您清理物品.因此,如果您这样做$scope.$on('someEvents', handleSomeEvent);,一旦范围被销毁(例如,当您转到应用程序中的另一个页面/视图时),该事件将自动删除.

需要注意的一件重要事情是$rootScope,除非您退出应用程序,否则当然不会被销毁.因此,如果您这样做$rootScope.$on('someEvents', handleSomeEvent);,您可能必须自己删除该事件,具体取决于您在何处收听事件:

  • 如果在a controller或者中directive,则必须手动删除它,否则每次实例化时controller,都会附加一个新事件,因此handleSomeEvent会多次调用
  • 如果在a中service,那么你不需要手动删除它,因为服务总是singleton(请注意,在Angular servicefactory,...最终都是同一件事)