4

具体来说,我想知道他们如何在不使用 innerHTML 的情况下更新元素。在文档中,他们清楚地说明了它们比其他模板引擎更好,因为它们不使用 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] (simplified)` 非常快速地更新每个节点,瞧,技术上没有 innerHTML'ing 和闪电般的 DOM 更新。

4

1 回答 1

5

与替换元素本身innerHTML不同,Angular 更喜欢修改现有元素的属性。

ng-bind指令实际上是一个很好的例子。它保留对 的引用,element并且只是将其更新.text()$scope更改(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);
  });
});

这并不一定意味着 AngularinnerHTML有时不会使用,尤其是在创建新内容时。但是,它会尽可能避免它。

于 2013-08-13T00:13:56.177 回答