gpt4 book ai didi

javascript - angularjs: ngModel controller $parser & $formatter 在元素被移除后仍然触发

转载 作者:数据小太阳 更新时间:2023-10-29 04:47:49 26 4
gpt4 key购买 nike

在下面的示例中,我不明白为什么在删除元素后 Angular 仍在触发解析器和格式化程序。我应该在指令中手动清理 ngModel Controller 吗?如果是这样,我应该怎么做?

要了解我在说什么,请查看 plunker,然后

  1. 打开控制台
  2. 点击“删除”按钮
  3. 点击“更改模型”按钮
  4. 注意格式化程序仍在启动

笨蛋:http://plnkr.co/edit/R7v5nB8JaQ91WcDGU8BC?p=preview

JS

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;
});
}
}
}]);

HTML

<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>

最佳答案

您的指令创建了自己的子作用域 - 这是一件好事。它拥有其上的所有 $watches,并且应该在其作用域被销毁后自行清理。

最好的做法是:

  1. 在设置 $watches 并计划稍后销毁该范围时创建一个子范围或隔离范围。由于该指令创建了范围,它也应该是在必要时销毁它并释放其所有 $watches 的指令。

  2. 检测元素何时被移除并在必要时销毁作用域。有时,如果您的 $watches 很重,并且您不希望它们在指令绑定(bind)到的元素从 DOM 中删除时徘徊,那么这样做有时是有意义的。如果删除是临时的——即切换元素的可见性,这可能没有意义

  3. 指令不应该破坏属于另一个的范围。即,如果您从父 Controller 继承范围,则让父 Controller 自行清理 - 这不是子指令的工作。

  4. 如果指令设置了任何 $watches,它应该监听范围 $destroy 事件,以便它可以注销它们。

  5. 如果指令已使用 on() 注册了任何 javascript 事件监听器,它应该在销毁作用域时使用 off() 注销它们。

通过处理 jQuery 元素 本身的 $destroy 事件,可以在从 DOM 中删除元素时执行清理:

// 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();
});
}

不应该必须在 ng-model 之后进行清理。当 $destroy 事件传播到子范围时,它将自行清理。如果所有指令都自行清理,那么在内存泄漏和孤立的 $watches 方面就不用担心了。

这是更新的 Plunker当元素被移除时,它会清理它的 $watches。

关于javascript - angularjs: ngModel controller $parser & $formatter 在元素被移除后仍然触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24701705/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com