Angular的*ngFor循环是如何实现的?

Dan*_*cal 2 angular-directive angular

我想知道Angular的*ngFor指令实际上是如何工作的?我想知道使用该指令时发生的整个过程.

对于downvoters:我已经看过ng-for-of文件,虽然没有单一用法传递给*ngFor数组,例如join()我知道调用的方法.感谢您的支持:)以下是显示行为的plunker:https://plnkr.co/edit/IXVxWrSOhLBgvSal6PWL?p = preview

Max*_*kyi 18

这是一个高级概述.假设您像这样定义模板:

<span *ngFor="let item of items">{{item}}</span>
Run Code Online (Sandbox Code Playgroud)

然后由编译器将其转换为以下内容:

<ng-template let-item [ngForOf]="items">
    <span>{{item}}</span>
</ng-template>
Run Code Online (Sandbox Code Playgroud)

然后Angular将ngForOf指令应用于模板元素.由于该指令的host元素是模板,因此它会注入templateRef.它还会注入viewContainerRef作为锚元素的角色,并将用于添加DOM元素:

  constructor(
       private _viewContainer: ViewContainerRef, 
       private _template: TemplateRef<NgForOfContext<T>>,
Run Code Online (Sandbox Code Playgroud)

该指令定义ngForOf为输入,然后等待它被初始化并创建一个不同的:

  ngOnChanges(changes: SimpleChanges): void {
      const value = changes['ngForOf'].currentValue;
          this._differ = this._differs.find(value).create(this.ngForTrackBy);
Run Code Online (Sandbox Code Playgroud)

然后在每个检查检测周期中,它使用以下差异将值与先前值进行比较:

  ngDoCheck(): void {
    if (this._differ) {
      const changes = this._differ.diff(this.ngForOf);
      if (changes) this._applyChanges(changes);
    }
  }
Run Code Online (Sandbox Code Playgroud)

如果值已更改,则会应用执行以下操作的更改:

1)为每个项目生成嵌入式视图上下文 items

context = new NgForOfContext<T>(null !, this.ngForOf, -1, -1)
Run Code Online (Sandbox Code Playgroud)

2)使用templateRef有效地在DOM中呈现新值的上下文创建嵌入视图

this._viewContainer.createEmbeddedView(
                this._template, context , currentIndex);
Run Code Online (Sandbox Code Playgroud)

3)将相关值添加到上下文中

  viewRef.context.index = i;
  viewRef.context.count = ilen;
  viewRef.context.$implicit = record.item;`
Run Code Online (Sandbox Code Playgroud)

现在,你的问题:

虽然它没有解释为什么在传递给的数组上调用e..g join()方法

它是由函数调用normalizeDebugBindingValue 这里,因为你的应用程序在开发模式下运行:

function normalizeDebugBindingValue(value: any): string {
  try {
    // Limit the size of the value as otherwise the DOM just gets polluted.
    return value != null ? value.toString().slice(0, 30) : value;
                           ^^^^^^^^^^^^^^^
  } catch (e) {
    return '[ERROR] Exception while trying to serialize the value';
  }
}
Run Code Online (Sandbox Code Playgroud)

如果启用生产模式,则不再调用此功能,请检查plunker.

  • 你对 `ngFor` 的解释很棒:) (4认同)
  • 是的,我应该更好地准备这个问题。老实说,我没想到它会受到如此多的关注,因为我的最后两个问题没有得到任何答案。再次感谢 (2认同)