将document.body.innerHTML应用于元素会禁用AngularJS功能

时间:2015-07-27 16:44:49

标签: javascript angularjs todomvc

为什么要对angular todo应用停止所有功能?

document.body.onload = function addElement() {
    document.body.innerHTML +=
        '<div  >'+
        '</div> ';
};

所有带有ng-click的按钮都不会调用各自的范围功能,按输入键会导致页面重新加载而不是添加新的待办事项。

演示提交:https://github.com/QuantumInformation/todomvc/commit/95ca6233a3e5b3a9775675c3f92d731ecc6032af

1 个答案:

答案 0 :(得分:2)

请记住,问题是指应该在任何网站上运行的实用程序,而不仅仅是Angular网站。如果您发现了这个问题并且正在构建一个Angular应用程序,则这不适用于您。它是构建AngularJS应用程序世界之外的一个非常具体的用例。

我认为@epascarello在评论中对此做了很好的解释,但重申:

您正在做的是获取当前页面上的HTML代码(不包括事件侦听器,$ scope绑定等)并重新呈现它的擦除版本,其中包含<div>端。

如果您有使用以下模板的指令:

<div>
    <p>{{person.name}}</p>
</div>

当Angular在页面上显示它通过将其绑定到$scope来编译它。所以实际页面上的HTML将是:

<div>
    <p>Nikos</p>
</div>

并且AngularJS将在person.name更改时更新该元素。如何发生这种情况是Angular存储对DOM元素的引用。不是字符串值,实际对象。但是,当您执行document.body.innerHTML = document.body.innerHTML += '<div></div>'时,您将获取HTML并创建该副本。现在,DOM元素AngularJS具有不存在的引用。页面上显示了一个新版本,但AngularJS并不了解它。

这样做的正确方法是:

document.body.appendChild(document.createElement('div'));