具体来说,我想知道他们如何在不使用 innerHTML 的情况下更新元素。在文档中,它们清楚地说明了它们比其他模板引擎更好的地方,因为它们 don't re-render with innerHTML (ctrl-f innerHTML——抱歉)。我开始浏览源代码,但其中有很多,希望我能从你们那里得到更快的答案。
到目前为止我的猜测是
- 编译器转换
{{test}}
变成类似<ng-bind>test</ng-bind>
的东西链接器可以在数据更改时更新它,但是当我查看呈现的 Angular 页面的 DOM 时,这似乎并没有发生。而且它似乎也可能会干扰客户端的 CSS 和 Angular 外部的其他 javascript 组件。 - 他们实际上正在使用 innerHTML,但他们只是没有重新呈现整个 DOM —— 只是其中的一小段(可能是某种自定义
<ng-bind></ng-bind>
标记中的数据)。 - 他们正在以某种方式删除和添加新元素……我认为这是糟糕的猜测。
如果有人知道我很乐意学习。否则它会为我返回源代码。
编辑新的猜测
再考虑之后,我相信这可能会发生:编译器吞下 html,说些类似的话
<p>
{{model}}
<div>
<p> Hello ! </p>
</div>
</p>
并将其转换为:
<p class="ng-binding">
{{model}}
<div>
<p> Hello ! </p>
</div>
</p>
然后 Angular 可以爬取并索引所有 Angular 文本节点 ( {{model}}
) eg document.getElementsByClass('ng-binding')[0].childNodes[0]
.然后链接器可以将每个存储的节点与范围模型关联$scope['model']
.然后可以通过设置 node.nodeValue = $scope['somemodel
非常快速地更新每个节点。 ] (简化)` 瞧,技术上没有 innerHTML'ing 和闪电般的 DOM 更新。
最佳答案
不像 innerHTML
那样替换元素本身,Angular 更喜欢修改现有元素的属性。
ng-bind
指令实际上就是一个很好的例子。它保留对 element
的引用,并在 $scope
更改时更新其 .text()
( source ):
var ngBindDirective = ngDirective(function(scope, element, attr) {
element.addClass('ng-binding').data('$binding', attr.ngBind);
scope.$watch(attr.ngBind, function ngBindWatchAction(value) {
element.text(value == undefined ? '' : value);
});
});
这并不一定意味着 Angular 有时不会使用 innerHTML
,尤其是在创建新内容时。但是,它会尽可能避免它。
关于javascript - AngularJS 如何更新 DOM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18198587/