我无法弄清楚为什么在以下示例中未触发$ destroy事件。有人可以解释为什么它没有被触发,在什么情况下它会被触发?
这里是傻瓜:http://plnkr.co/edit/3Fz50aNeuculWKJ22iAX?p=preview
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');
})
}
}
}]);
<body ng-controller='testCtrl'>
<div testDir id='test'>I will be removed.</div>
<button ng-click='removeElem('test')'>remove</button>
</body>
答案 0 :(得分:24)
问题是您正在$destroy
上收听scope
事件,但$destroy
正在触发element
。
来自angular.js来源(我确定它已经在某个地方的网站上记录过了,但我没看过):
$destroy
- AngularJS拦截所有jqLite / jQuery的DOM破坏 apis并在被删除的所有DOM节点上触发此事件。这个可以 用于清理之前的任何第三方绑定到DOM元素 它被删除了。
您的指示应该是(请注意,我添加了scope
,element
和attrs
作为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事件在两种情况下被触发。
- 在范围被销毁之前
- 在从DOM中删除元素之前
醇>
目的是&#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