假设这样定义模版:
<span *ngFor="let item of items">{{item}}</span>
然后由编译器将其转换为以下内容:
<ng-template let-item [ngForOf]="items">
<span>{{item}}</span>
</ng-template>
然后,Angular将ngForOf指令应用于模板元素。 由于此指令的宿主元素是template,因此将注入templateRef。 它还将注入充当锚元素的viewContainerRef并将用于在旁边添加DOM元素:
constructor(
private _viewContainer: ViewContainerRef,
private _template: TemplateRef<NgForOfContext<T>>,
......
该指令将ngForOf定义为@Inout,然后等待它被初始化并创建一个differ:
ngOnChanges(changes: SimpleChanges): void {
const value = changes['ngForOf'].currentValue;
this._differ = this._differs.find(value).create(this.ngForTrackBy);
......
然后,在每个检查检测周期中,它使用以下差异将值与以前的值进行比较:
ngDoCheck(): void {
if (this._differ) {
const changes = this._differ.diff(this.ngForOf);
if (changes) this._applyChanges(changes);
}
}
如果值更改,它将执行以下操作来应用更改:
-
generates embedded view context for each item in items
context = new NgForOfContext(null !, this.ngForOf, -1, -1)
-
creates embedded view with this context using the templateRef which effectively renders new value in the DOM
this._viewContainer.createEmbeddedView(
this._template, context , currentIndex); -
adds relevant values to context
viewRef.context.index = i;
viewRef.context.count = ilen;
viewRef.context.$implicit = record.item;`