我不明白为什么在下面的例子中没有触发$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
事件,但$destroy
在element
上被触发。
来自angular.js的源代码(我确信它在网站的某个地方记录了,但我没有看):
$destroy
- AngularJS拦截所有jqLite/jQuery的DOM销毁并在所有被删除的DOM节点上触发此事件。这可以用于清除之前对DOM元素的任何第三方绑定
您的指令应该是(请注意,我添加了scope
, element
和attrs
作为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事件在两种情况下被触发。
- 在作用域被销毁之前
- 在元素从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