AngularJS如何更新DOM?

vin*_*vin 4 javascript angularjs

具体来说,我想知道他们如何在不使用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>
Run Code Online (Sandbox Code Playgroud)

并将其转换为:

<p class="ng-binding"> 
  {{model}} 
  <div> 
    <p> Hello ! </p> 
  </div> 
</p>
Run Code Online (Sandbox Code Playgroud)

然后Angular可以爬行并索引所有角度文本节点({{model}})eg document.getElementsByClass('ng-binding')[0].childNodes[0].然后,链接器可以将每个存储的节点与范围模型相关联$scope['model'].然后,通过设置node.nodeValue = $scope['somemodel](简化)`和vo技术,没有内部HTML和闪电速度DOM更新,可以非常快速地更新每个节点.

Jon*_*ski 5

innerHTMLAngular 不像更换元素本身,而是更喜欢修改现有元素的属性.

ng-bind指令实际上是一个很好的例子.它保留了element对它的引用,并将其更新.text()$scope更改():

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);
  });
});
Run Code Online (Sandbox Code Playgroud)

这并不一定意味着Angular innerHTML有时不会使用,特别是在创建新内容时.但是,它尽可能避免它.