如果移除并重新添加DOM元素,则ng-click绑定将丢失

时间:2015-02-23 12:48:52

标签: javascript angularjs angularjs-ng-click

我需要在删除之后将以前编译的角度html重新添加回DOM树(see here for background reasons)。

内容绑定仍然按预期工作。例如当范围变量更改时,任何{{someVariable}}绑定都会使用新值更新。

然而ng-click绑定停止工作。控制器上的相关功能停止被调用。

See this fiddle for repro。最初单击+按钮,您将看到计数器增量。但是点击两次切换后,+按钮不再有效,但{{count}}绑定仍然会更新。

请忽略控制器中的DOM操作。这只是为了简化repro。您通常会在指令中执行此操作。有关更实际的实施,请参阅my original questionJoe's answer

4 个答案:

答案 0 :(得分:3)

我已经使用了jquery这么久我忘记了一些陷阱。

  

.detach()方法与.remove()相同,除了.detach()保留与删除的元素关联的所有jQuery数据。当删除的元素稍后要重新插入DOM时,此方法很有用。

http://api.jquery.com/detach/

当然,角度的jqlite遵循相同的惯例。因此,对replaceWith的调用会删除ng-click附加的事件处理程序。相反,使用detachappend会保留事件处理程序,一切都按预期工作:

http://jsfiddle.net/sxm22w3b/17/

答案 1 :(得分:1)

您必须首先使用所需的范围重新编译它。

请参见此处:http://fiddle.jshell.net/andyw_/72NYm/

我首先编译模板,然后在此处插入此行:

var targetFn = $compile(target);

您可以参考文档了解更多信息 - https://docs.angularjs.org/guide/compiler#how-directives-are-compiled

答案 2 :(得分:1)

使用detach()。

  old.before( new ).detach()

相当于replaceWith()

答案 3 :(得分:0)

您可以参考以下解决方案:

HTML:

<div ng-controller="Ctrl">
    <button ng-click="toggle()">Toggle</button>
    <div ng-show="showContent" id="toggleTarget">
        Some content = {{myContent}}
        <button ng-click="inc()">+</button>
    </div>
    <div id="placeholder" ng-show="showplaceholder">Placeholder</div>
</div>

JS:

function Ctrl($rootScope, $scope, $element) {
    $scope.myContent = 1;

    var target = angular.element(document.getElementById("toggleTarget"));
    var placeholder = angular.element(document.getElementById("placeholder"));

    var removed = false;
    $scope.showContent = true;
    $scope.placeholder = false;

    $scope.toggle = function(){
        $scope.myContent += 1;

        if (removed) {
            $scope.showContent = true;
            $scope.placeholder = false;
            removed = false;
        }
        else {
            $scope.showContent = false;
            $scope.placeholder = true;
            removed = true;
        }    
    }

    $scope.inc = function(){
        $scope.myContent += 1;
    };
}

angular.module('app', []);

上面的代码给出了相应的输出。如果您想获得输出,请检查此代码并标记为有用。