Angular2 - ngIf - 源码解读

先上源码

@Directive({selector: '[ngIf]', inputs: ['ngIf']})
export class NgIf {
private _prevCondition: boolean = null;

constructor(private _viewContainer: ViewContainerRef, private _templateRef: TemplateRef) {}

set ngIf(newCondition /* boolean */) {
if (newCondition && (isBlank(this._prevCondition) || !this._prevCondition)) {
this._prevCondition = true;
this._viewContainer.createEmbeddedView(this._templateRef);
} else if (!newCondition && (isBlank(this._prevCondition) || this._prevCondition)) {
this._prevCondition = false;
this._viewContainer.clear();
}
}
}

明确

  • ngIf 这个指令是接受参数的属性指令
  • 指令内部会嵌入html(包括ngIf所在的元素)

传入的参数用的 inputs: [‘ngIf’] 来接收, 因为他的template展开后是这样的

 <div *ngIf="condition">...</div>
<div template="ngIf condition">...</div>
<template [ngIf]="condition"><div>...</div></template>
  • _prevCondition - 上一次的条件。为了后面判断是否变化,另外的作用是默认值

  • _viewContainer 类型是ViewContainerRef,这个东西一般就是host。就是有这个指令的元素

  • _templateRef 类型是 TemplateRef 理解为 里面嵌入的html代码

简单解读条件:

if (newCondition && (isBlank(this._prevCondition) || !this._prevCondition)) {
this._prevCondition = true;
this._viewContainer.createEmbeddedView(this._templateRef);
}
  • 新的条件如果是true 并且 之前是null(默认值)或者 之前是false

    • 相当于第一次进来的时候 isBlank(this._prevCondition) 是true, 只有newCondition 为true的时候走下面
    • 如果不是第一次,必须之前是false (!this._prevCondition)并且新条件是true。即条件变化了才执行下面
  • 更新_prevCondition为true, 显示嵌入的view 所以他把嵌入的html created了并放在_viewContainer里面

    else 反之