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

Applying document.body.innerHTML to element disables AngularJS functionality

为什么对 angular todo 应用程序执行此操作会停止所有功能?

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

所有带有 ng-click 的按钮都不会调用它们各自的范围函数,并且在输入上按 enter 会导致页面重新加载而不是添加新的待办事项。

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

请记住,该问题指的是应该适用于任何网站的实用程序,而不仅仅是 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'));