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

时间:2014-07-10 02:21:04

标签: angularjs angularjs-directive angularjs-scope

我无法弄清楚为什么在以下示例中未触发$ 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>

2 个答案:

答案 0 :(得分:24)

问题是您正在$destroy上收听scope事件,但$destroy正在触发element

来自angular.js来源(我确定它已经在某个地方的网站上记录过了,但我没看过):

  

$destroy - AngularJS拦截所有jqLit​​e / jQuery的DOM破坏   apis并在被删除的所有DOM节点上触发此事件。这个可以   用于清理之前的任何第三方绑定到DOM元素   它被删除了。

您的指示应该是(请注意,我添加了scopeelementattrs作为link参数):此外,这里是plunker

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

答案 1 :(得分:1)

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

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

  
      
  1. 在范围被销毁之前
  2.   
  3. 在从DOM中删除元素之前
  4.   

目的是&#34;清理&#34;。您可以在销毁范围或元素之前监听$ 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