在AngularJS中删除DOM元素之前我该怎么办?

时间:2016-11-02 04:05:04

标签: javascript angularjs dom angularjs-directive angularjs-scope

我记得在将它从DOM中删除之前需要先破坏元素的范围。但我不确定如何做到这一点。

所以,碰巧我有一个从DOM中删除元素的指令。精简版本如下:

(function() {
    angular.module('app').directive('remove', function() {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                element.children().remove();
                element.remove();
            }
        }
    }]);
}());

一个简单而不切实际的例子就是这样的 <my-directive-with-isolated-scope remove></my-directive-with-isolated-scope>

我可以删除该元素,但看起来似乎没有销毁范围,我认为会造成内存泄漏吗?我还在指令的控制器(具有隔离范围的控制器)中设置了$interval,在那里我设置了一个控制台消息作为测试。我可以看到,当它从DOM中删除时,它仍然以设定的间隔注销控制台消息。

我是否会修改上述指令中的某些内容以便正确删除该元素?

3 个答案:

答案 0 :(得分:1)

您尝试使用元素/范围破坏的几个实验:

您可以进行测试以查看范围何时被销毁:

scope.$on('$destroy', function(){
    console.log('Scope Destroyed!');
});

您还可以测试被销毁的元素:

element.on('$destroy', function(){
    console.log('Element Destroyed!');
});

(请参阅angular.element docs活动部分)

现在,关于间隔:

$interval将一直运行到$interval.cancel(),无论范围是否存在(除非回调是某个绑定到scope的函数,在这种情况下回调可能会变为未定义,我和#39;我不确定$interval如何处理这个问题。

如果您的指令正在运行$interval函数,则可能包含以下内容:

var count = 0;
var timer = 
    $interval( function doingStuff () {
        console.log( count + ' seconds ...' );
    }, 1000 );

scope.$on('$destroy', function cleanup () {
    $interval.cancel( timer );
});

关于需要手动销毁范围:

如果您通过var myScope = $scope.$new();手动创建范围,则您有责任通过myScope.$destroy();销毁该范围。我想说这是一个更高级的用法,我无法想到手动创建新范围的任何真正常见的原因。 (也许如果你的指令是用一个全新的范围来创建一个元素和$compile

答案 1 :(得分:0)

如果元素是从作用域生成的,则应该销毁它,删除作用域数据并让角度重新渲染它,而不是使用DOM操作。范围数据与DOM元素本身无关,该元素就是根据范围呈现的内容。因此,删除元素不会对范围变量产生任何影响。

您不应该使用指令来执行此操作;更改或删除范围中的值。

答案 2 :(得分:0)

向DOM添加元素的ng-viewng-ifng-repeatng-include等指令,首先创建子范围,然后使用{{ 1}}在将这些元素附加到DOM之前,将这些元素编译并链接到该子作用域的服务。这些编译的元素链接到创建的子范围。当这些指令随后删除这些元素时,它们也会破坏子范围。

创建子范围:

$compile

要销毁该子范围:

var childScope = scope.$new();

有关详细信息,请参阅AngularJS rootScope.scope API Reference