Tim*_*Mac 7 javascript angularjs angularjs-directive
在下面的例子中,我不明白为什么在删除元素后,angular仍然会解析解析器和格式化程序.我应该在指令中手动清理ngModel控制器吗?如果是这样,我该怎么做?
要查看我在说什么,请查看plunker,和
plunker:http://plnkr.co/edit/R7v5nB8JaQ91WcDGU8BC?p = preview
angular.module('testMod', [])
.controller('testCtrl', function($scope){
$scope.test = "test";
$scope.removeElem = function(id) {
var elem = document.getElementById(id);
angular.element(elem).remove();
}
}).directive('testDir',[function() {
return {
require: 'ngModel',
scope:true,
link: function(scope, elem, attr, ctrl) {
console.log('in directive');
ctrl.$parsers.unshift(function (newValue) {
console.log('directive parser');
return newValue;
});
ctrl.$formatters.unshift(function (newValue) {
console.log('directive formatter');
return newValue;
});
}
}
}]);
Run Code Online (Sandbox Code Playgroud)
<body ng-controller='testCtrl'>
<input id='test' test-dir ng-model='test'/>
<button ng-click="removeElem('test')">remove</button>
<button ng-click="test = test + 'a'">change model</button>
<div>{{test}}</div>
</body>
Run Code Online (Sandbox Code Playgroud)
您的指令创建了自己的子作用域 - 这是一件好事。它拥有其上的所有 $watches,并且应该在其作用域被销毁时自行清理。
好的做法是:
当您设置 $watches 时创建一个子作用域或隔离作用域并计划稍后销毁该作用域。由于该指令创建了作用域,因此它也应该是在必要时销毁它并释放其所有 $watch 的指令。
检测元素何时被移除,并在必要时销毁示波器。有时,如果您的 $watches 很重,并且您不希望它们在指令绑定的元素从 DOM 中删除时徘徊,那么这样做是有意义的。如果删除是临时的,这可能没有意义 - 即切换元素的可见性
指令永远不应该破坏属于另一个指令的作用域。即,如果您从父控制器继承了范围,则让父控制器自行清理 - 这不是子指令的工作。
如果指令设置了任何 $watches,它应该侦听作用域 $destroy 事件,以便可以取消注册它们。
如果该指令已使用 on() 注册了任何 javascript 事件侦听器,则当作用域被销毁时,它应该使用 off() 取消注册它们。
当一个元素从 DOM 中删除时,可以通过处理jQuery 元素本身的 $destroy 事件来执行清理:
// creates a child scope owned by the directive
scope: true,
link: function(scope, element, attr) {
// set up a click handler
element.on('click', function() {
...
});
// set up a $watch on the child scope. It returns a
// function that you can call to unregister the $watch
var unregister = scope.$watch('test', function() {
...
});
// when the element is removed from the DOM,
// destroy the scope and all its $watches.
element.on('$destroy', function() {
// remove the $watch
unregister();
// remove the click handler
element.off('click');
// call $destroy on the child scope
// so that it can propagate to any children
scope.$destroy();
});
}
Run Code Online (Sandbox Code Playgroud)
您不必在 ng-model 之后进行清理。当 $destroy 事件传播到子作用域时,它将自行清理。如果所有指令都自行清理,那么当涉及到内存泄漏和孤立的 $watches 时,就不用担心很多了。
这是一个更新的Plunker,当元素被删除时,它会清理它的 $watches。
| 归档时间: |
|
| 查看次数: |
2332 次 |
| 最近记录: |