Angular的* ngFor循环如何实现? [英] How is Angular's *ngFor loop implemented?

查看:746
本文介绍了Angular的* ngFor循环如何实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wonder how does Angular's *ngFor directive actually work under the hood? I would like to know the whole process that happens when I use the directive.

不赞成投票的人:我见过 https://plnkr.co/edit/IXVxWrSOhLBgvSal6PWL?p=预览

For downvoters: I've seen the ng-for-of file, although there is no single usage of passed to *ngFor array's e.g. join() method that I know is invoked. Thanks for your support :) Here is the plunker that shows the behavior: https://plnkr.co/edit/IXVxWrSOhLBgvSal6PWL?p=preview

推荐答案

以下是高级概述.假设您这样定义模板:

Here is a high level overview. Suppose you define your template like this:

<span *ngFor="let item of items">{{item}}</span>

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

Then it's transformed to the following by the compiler:

<ng-template let-item [ngForOf]="items">
    <span>{{item}}</span>
</ng-template>

然后Angular将ngForOf指令应用于模板元素.由于此伪指令的宿主元素是模板,因此将注入templateRef.它还会注入用作锚元素的viewContainerRef,并将其用于在旁边添加DOM元素:

Then Angular applies ngForOf directive to the template element. Since this directive's host element is template, it injects the templateRef. It also injects the viewContainerRef that acts as an anchor element and will be used to add DOM elements alongside:

  constructor(
       private _viewContainer: ViewContainerRef, 
       private _template: TemplateRef<NgForOfContext<T>>,

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

The directive defines ngForOf as an input and then waits until it's initialized and creates a differ:

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

然后在每个支票检测周期中,使用以下不同之处将值与以前的值进行比较:

Then on each check detection cycle it compares the values to the previous values using this differ:

  ngDoCheck(): void {
    if (this._differ) {
      const changes = this._differ.diff(this.ngForOf);
      if (changes) this._applyChanges(changes);
    }
  }

如果值发生更改,它将执行以下操作来应用更改:

If the values changed, it applies the changes doing the the following things:

1)为items

context = new NgForOfContext<T>(null !, this.ngForOf, -1, -1)

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

2) creates embedded view with this context using the templateRef which effectively renders new value in the DOM

this._viewContainer.createEmbeddedView(
                this._template, context , currentIndex);

3)向上下文添加相关值

3) adds relevant values to context

  viewRef.context.index = i;
  viewRef.context.count = ilen;
  viewRef.context.$implicit = record.item;`

现在,您的问题:

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

although it doesn't explain why e..g join() method is invoked on array passed to

由函数normalizeDebugBindingValue调用

It's called by the function normalizeDebugBindingValue here because your application is running in the development mode:

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';
  }
}

如果启用生产模式,将不再调用此功能.检查矮人.

If you enable production mode, this function will no longer be called. Check the plunker.

这篇关于Angular的* ngFor循环如何实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆