Javascript 仍在向损坏的控制器范围angularjs广播

Javascript 仍在向损坏的控制器范围angularjs广播,javascript,angularjs,Javascript,Angularjs,我有一个指令,它的回调如下所示: function Callback(){ return { templateUrl: 'somePath', scope: true, link: function(scope, el) { scope.cancel = function(){ el.remove() scope.$destroy() } }, contro

我有一个指令,它的回调如下所示:

function Callback(){
    return {
      templateUrl: 'somePath',
      scope: true,
      link: function(scope, el) {
        scope.cancel = function(){
          el.remove()
          scope.$destroy()
        }
      },
      controller: 'someController',
      controllerAs: 'vm'
    }
  }
link方法只是添加了一个cancel方法,用于从DOM中删除该指令

在指令控制器中,我正在侦听一个事件:

$rootScope.$on('parent', function(){
  someService.addToArray(someData)
})
此方法仅将数据推送到数组

在父控制器和视图中,在使用该指令的地方,我实际上正在启动广播。父控制器的一部分:

var vm = this
vm.broadcastEvent = broadcastEvent      
function broadcastEvent(){
  $rootScope.$broadcast('someEvent', 'someData')
}
在视图中,我有一些可点击的div,它触发了这个方法

它工作得很好,在我移除元素并销毁作用域之前,指令会听到广播并将数据添加到数组中

问题是,在我调用
.cancel
之后,元素被删除,可能作用域被破坏,但它仍然向数组添加数据。我是否遗漏了
scope.$destroy()
的工作原理


我可以通过在上取消注册
$来获得我想要的行为,我是否需要这样做?我想问题是,销毁控制器作用域会否定其中定义的任何
$,还是需要确保在销毁作用域之前明确取消注册。

我不确定是否正确调用了
作用域。$destroy()

正如文件中所写:

从父对象中删除当前作用域(及其所有子对象) 范围[…]注意,在AngularJS中,还有一个$destroy jQuery 事件,可用于在创建元素之前清理DOM绑定 从DOM中删除

所以,我认为你应该这样做:

link: function(scope, el) {
        el.on('$destroy', function() {
          scope.$destroy();
        });

        scope.cancel = function(){
          el.remove();
        }
      }

告诉我它是否解决了您的问题

侦听器函数已在$rootScope上注册,并将在指令$scope被销毁后继续存在:

$rootScope.$on('parent', function listener(){
  someService.addToArray(someData)
})
该控制器需要保存调用$rootScope.$on方法返回的注销函数:

this.deregister = $rootScope.$on('parent', function listener(){
  someService.addToArray(someData)
})
取消功能需要调用取消注册功能:

  link: function(scope, el) {
    scope.cancel = function(){
      el.remove()
      scope.$destroy()
      scope.vm.deregister()
    }
  },
  controller: 'someController',
  controllerAs: 'vm'


取消注册不应该在范围被销毁之前发生吗

没关系。正如您所发现的,由于侦听器是在$rootScope上注册的,所以它存储在$rootScope上的一个数组中(特别是
$rootScope.$$listeners
)。通过调用取消注册函数,它将从
$rootScope.$$listeners
中删除

面向对象运行时(如JavaScript)的本质是,只有当对对象的所有引用都被销毁时,才会从内存中删除对象(垃圾收集)。由于侦听器函数的引用存储在$rootScope上,因此它(及其执行上下文)仍然存在


如果侦听器已在指令$scope上注册,则当作用域被销毁时,它将自动取消注册。

是的,这正是我最终要做的,而且在我写问题时,它更有意义。一如既往地感谢@georgeawg!取消注册不应该在范围被销毁之前发生吗?