Javascript angular.js$destroy事件-我应该手动解除绑定吗?

Javascript angular.js$destroy事件-我应该手动解除绑定吗?,javascript,angularjs,angularjs-scope,Javascript,Angularjs,Angularjs Scope,我试图弄清楚angular base在(…)或($scope.$scope.$上(…)或($scope.$watch(…)范围被销毁时,是否会自动解除与$scope.$绑定的监视程序和范围事件的绑定 假设我有以下代码: $scope.$on('someEvents', handleSomeEvent); $scope.$watch('someProperty', handleSomePropertyChange); 当作用域上触发$destroy event时,是否需要手动解除绑定这些监视程序

我试图弄清楚angular base在(…)或(
$scope.$scope.$上(…)
或(
$scope.$watch(…)
范围被销毁时,是否会自动解除与
$scope.$绑定的监视程序和范围事件的绑定

假设我有以下代码:

$scope.$on('someEvents', handleSomeEvent);
$scope.$watch('someProperty', handleSomePropertyChange);

当作用域上触发$destroy event时,是否需要手动解除绑定这些监视程序和事件?

如果作用域位于控制器中,请为您解除绑定。否则,可以通过调用返回的函数解除事件绑定:

var myevent = $scope.$on('someEvents', handleSomeEvent);
myevent() ; // unbind the event

根据:

如果希望某个作用域及其子作用域与父作用域永久分离,从而通过调用停止参与模型更改检测和侦听器通知,则必须对该作用域调用“$destroy()”

删除还意味着当前作用域有资格进行垃圾收集

因此,当调用
$destroy()
时,所有的观察者和监听器都将被删除,表示作用域的对象将成为符合垃圾收集条件的

如果我们看一下
destroy()
,我们会看到一行:

forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
它应该删除所有侦听器

正如@glepretre所提到的,它适用于控制器中的观察者和监听者。上面列出的同一个文档页面说明:

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


因此,如果您在指令中有特定的侦听器,您应该侦听
$destroy
事件,并按照前面的回答自己进行必要的清理,Angular确实会尽可能为您清理东西。因此,如果您执行('someEvents',handleSomeEvent')上的
$scope.$on,一旦范围被销毁(例如,当您转到应用程序中的另一个页面/视图时),事件将自动删除

不过需要注意的一点是,
$rootScope
当然不会被销毁,除非你退出应用程序。因此,如果您执行
$rootScope.$on('someEvents',handleSomeEvent),您可能必须自己删除事件,具体取决于您收听事件的位置:

  • 如果在
    控制器
    指令
    中,则必须手动删除它,否则每次实例化
    控制器
    ,都会附加一个新事件,因此将多次调用
    handleSomeEvent
  • 如果在
    服务中
    ,则无需手动将其删除,因为服务始终是
    单例
    (请注意,在
    服务中,
    工厂
    ,所有服务最终都是相同的)

这取决于您在何处设置了
$watch
,如果它在指令中。我知道我需要为$destroy事件上的所有非角度绑定手动执行此操作。虽然我错过了关于“…停止参与模型更改检测和侦听器通知…”的部分,但很抱歉,读完后我仍然不明白:$scope.$on和$scope.$watch是自动解除绑定的,还是应该在销毁事件中解除绑定?
$scope
上的所有观察者都解除了绑定自动地但是,您应该在
$rootScope
和指令内的DOM元素上手动解除绑定侦听器。您会看到一些角度文件(一个为ng网格)的模式,其中角度开发人员使用此模式解除$scope中$watch的绑定:
$scope.$on('$destroy',$scope.$watch('renderedColumns',function(){//do stuff}),它只是将取消$watch的函数直接传递给$destroy事件侦听器。您是如何发现这一点的?我假设您也在为指令中的
控制器
语法说话?这是否也意味着链接函数中的任何作用域都不会解除绑定?事实上,这种自动取消注册通常适用于作用域、控制器以及指令。这是因为当删除控制器或从DOM中删除元素时,会触发销毁事件。此事件取消绑定相关作用域上的所有事件。这意味着您必须关心$rootScope上添加的事件,因为它从未被删除。您可以在此处阅读一些信息:范围生命周期:销毁事件:元素上的销毁事件: