ngIf 指令用于根据表达式的值,在指定位置渲染 then 或 else 模板的内容。
简单形式
使用else块
使用then和else块
使用as语法
@ViewChild('primaryBlock') primaryBlock: TemplateRef = null; @ViewChild('secondaryBlock') secondaryBlock: TemplateRef = null;
switchPrimary() { this.thenBlock = this.thenBlock === this.primaryBlock ? this.secondaryBlock : this.primaryBlock; }
ngOnInit() { this.thenBlock = this.primaryBlock; } }
ViewContainerRef 实例提供了 createEmbeddedView() 方法,该方法接收 TemplateRef 对象作为参数,并将模板中的内容作为容器 (comment 元素) 的兄弟元素,插入到页面中。
createEmbeddedView()
TemplateRef
NgIfContext 实例用于表示 NgIf 上下文。
// 表示根据then模板创建的EmbeddedViewRef视图 private _thenViewRef: EmbeddedViewRef|null = null; // 表示根据else模板创建的EmbeddedViewRef视图 private _elseViewRef: EmbeddedViewRef|null = null;
constructor( private _viewContainer: ViewContainerRef,templateRef: TemplateRef) { this._thenTemplateRef = templateRef; // then模板的默认值为ngIf指令关联的内联模板 } }
@Input() set ngIfElse(templateRef: TemplateRef) { this._elseTemplateRef = templateRef; this._elseViewRef = null; // 清除之前创建的视图 this._updateView(); }
ngIf 指令的源码相对比较简单,最核心的是 _updateView() 方法。而该方法中最重要的功能就是如何基于模板对象创建内嵌视图。接下来我们来分析一下 ViewContainerRef 对象的 createEmbeddedView() 方法。
ngIf
_updateView()
ViewContainerRef
方法签名
方法实现
// ViewContainerData接口继承于ViewContainerRef抽象类 export interface ViewContainerData extends ViewContainerRef { _embeddedViews: ViewData[]; }
export interface ViewData { def: ViewDefinition; root: RootData; renderer: Renderer2; parentNodeDef: NodeDef|null; parent: ViewData|null; viewContainerParent: ViewData|null; component: any; context: any; nodes: {[key: number]: NodeData}; state: ViewState; oldValues: any[]; disposables: DisposableFn[]|null; }
通过观察 ViewContainerRef_ 类中的 createEmbeddedView() 方法,我们发现该方法内部是调用 TemplateRef 对象的 createEmbeddedView() 方法来创建内嵌视图。因此接下来我们再来分析一下 TemplateRef 对象的 createEmbeddedView() 方法。
ViewContainerRef_
export interface TemplateData extends TemplateRef { _projectedViews: ViewData[]; }
看完上面的源码,毫无疑问接下来我们要继续分析 Services 对象中的 createEmbeddedView() 方法。
Services
Services 对象定义
Services 对象初始化
在 initServicesIfNeeded() 方法中,会根据当前所处的模式,创建不同的 Services 对象。接下来 我们直接来看一下 createProdServices() 方法:
initServicesIfNeeded()
createProdServices()
此时发现如果完整分析所有的方法,会涉及太多的内容。源码分析就到此结束,有兴趣的读者请自行阅读源码哈(请各位读者见谅)。接下来我们来总结一下 createEmbeddedView() 方法调用流程:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。