我们可以使用ng-container, ng-template和ngTemplateOutlet 三者的配合,实现动态渲染某个模板视图的目的。
ng build之后,在Chrome开发者工具里看到ng文件夹下对应的html文件:
<ng-template #inputTemplate>
<input>
<h1>ngTemplateOutlet的用法</h1>
</ng-template>
<ng-container *ngTemplateOutlet="inputTemplate"></ng-container>
tNode指向源代码里的ng-container节点:
ngTemplateOutlet的实现:
/**
* @ngModule CommonModule
*
* @description
*
* Inserts an embedded view from a prepared `TemplateRef`.
*
* You can attach a context object to the `EmbeddedViewRef` by setting `[ngTemplateOutletContext]`.
* `[ngTemplateOutletContext]` should be an object, the object's keys will be available for binding
* by the local template `let` declarations.
*
* @usageNotes
* ```
* <ng-container *ngTemplateOutlet="templateRefExp; context: contextExp"></ng-container>
* ```
*
* Using the key `$implicit` in the context object will set its value as default.
*
* ### Example
*
* {@example common/ngTemplateOutlet/ts/module.ts region='NgTemplateOutlet'}
*
* @publicApi
*/
@Directive({selector: '[ngTemplateOutlet]'})
export class NgTemplateOutlet implements OnChanges {
private _viewRef: EmbeddedViewRef<any>|null = null;
/**
* A context object to attach to the {@link EmbeddedViewRef}. This should be an
* object, the object's keys will be available for binding by the local template `let`
* declarations.
* Using the key `$implicit` in the context object will set its value as default.
*/
@Input() public ngTemplateOutletContext: Object|null = null;
/**
* A string defining the template reference and optionally the context object for the template.
*/
@Input() public ngTemplateOutlet: TemplateRef<any>|null = null;
constructor(private _viewContainerRef: ViewContainerRef) {}
ngOnChanges(changes: SimpleChanges) {
const recreateView = this._shouldRecreateView(changes);
if (recreateView) {
const viewContainerRef = this._viewContainerRef;
if (this._viewRef) {
viewContainerRef.remove(viewContainerRef.indexOf(this._viewRef));
}
this._viewRef = this.ngTemplateOutlet ?
viewContainerRef.createEmbeddedView(this.ngTemplateOutlet, this.ngTemplateOutletContext) :
null;
} else if (this._viewRef && this.ngTemplateOutletContext) {
this._updateExistingContext(this.ngTemplateOutletContext);
}
}
还是老套路,在ngOnChanges里调用ViewContainerRef.createEmbeddedView:
更多Jerry的原创文章,尽在:“汪子熙”: