为什么当我调用element.remove时没有触发$destroy?



我不明白为什么在下面的例子中没有触发$destroy事件。有人能解释一下为什么它没有被触发,以及在什么情况下它会被触发吗?

这是活塞:http://plnkr.co/edit/3Fz50aNeuculWKJ22iAX?p=preview

JS

angular.module('testMod', [])
.controller('testCtrl', function($scope){
  $scope.removeElem = function(id) {
    var elem = document.getElementById(id);
    angular.element(elem).remove();
  }
}).directive('testDir',[function() {
  return {
    scope:true,
    link: function(scope) {
      console.log('in directive');
      scope.$on('$destroy', function(){
        alert('destroyed');
      })
    }
  }
}]);

HTML

<body ng-controller='testCtrl'>
  <div testDir id='test'>I will be removed.</div>
  <button ng-click='removeElem('test')'>remove</button>
</body>

问题是您侦听scope上的$destroy事件,但$destroyelement上被触发。

来自angular.js的源代码(我确信它在网站的某个地方记录了,但我没有看):

$destroy - AngularJS拦截所有jqLite/jQuery的DOM销毁并在所有被删除的DOM节点上触发此事件。这可以用于清除之前对DOM元素的任何第三方绑定

您的指令应该是(请注意,我添加了scope, elementattrs作为link参数):此外,这里是一个柱塞。

directive('testDir',[function() {
  return {
    scope:true,
    link: function(scope,element,attrs) {
      console.log('in directive');
      element.on('$destroy', function(){
        alert('destroyed');
      })
    }
  };
}]);

我很困惑为什么在remove()方法上没有触发$destroy事件

根据文档,$destroy事件在两种情况下被触发。

  1. 在作用域被销毁之前
  2. 在元素从DOM中移除之前

目的是"清理"。您可以监听$destroy事件,并在销毁作用域或元素之前执行必要的清理。ngIf、ngSwitch、ngRepeat和其他内置指令/方法使用$destroy事件来执行清理。

一个最好的例子是ngRepeat指令 https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js

在第339行,您可以注意到$destroy事件被触发。你可以监听事件,并在一个项目从ngRepeat使用的列表中删除之前执行任何操作。

ngRepeat $destroy示例Plunk——http://goo.gl/mkozCY

最新更新