我对createEmbeddedView和createComponent的用例感到困惑,即什么时候使用哪一个.请提出一些案例,告诉他们在“动态创建场景”中使用其中任何一个的合适设置
请参阅
this workshop on DOM manipulation或阅读
Working with DOM in Angular: unexpected consequences and optimization techniques,其中我解释了与示例的区别.
这两种方法都用于动态地将内容添加到组件视图(DOM).此内容可以是模板,也可以是基于组件.在Angular中,我们通常使用ViewContainerRef操作DOM.这两种方法都可以使用:
class ViewContainerRef { ... createEmbeddedView<C>(templateRef: TemplateRef<C>,context?: C,index?: number): EmbeddedViewRef<C> createComponent<C>(componentFactory: ComponentFactory<C>,index?: number,injector?: Injector,projectableNodes?: any[][],ngModule?: NgModuleRef<any>): ComponentRef<C> }
要了解有关操纵DOM的更多信息,请阅读Exploring Angular DOM manipulation techniques using ViewContainerRef.
createEmbeddedView
它用于使用TemplateRef创建视图.当Angular编译器在组件html中遇到ng-template标记时,会创建TemplateRef.
使用此方法创建的视图称为嵌入视图.
import { VERSION,Component,ViewChild,TemplateRef,ViewContainerRef } from '@angular/core'; @Component({ selector: 'my-app',template: ` <ng-container #vc></ng-container> <ng-template #tpl> <h1>Hello,{{name}}</h1> </ng-template> `,styles: [''] }) export class AppComponent { name = `Angular! v${VERSION.full}`; @ViewChild('tpl',{read: TemplateRef}) tpl: TemplateRef<any>; @ViewChild('vc',{read: ViewContainerRef}) vc: ViewContainerRef; ngOnInit() { this.vc.createEmbeddedView(this.tpl); } }
所有结构指令(如* ngIf和* ngFor)都使用此方法,因为它们都包含ng-template.例如,对于* ngFor代码:
<div *ngIf="data">{{name}}</div>
变成了
<ng-template ngIf="data"> <div>{{name}}</div>
并且ngIf指令在内部使用createEmbeddedView:
@Directive({selector: '[ngIf]'}) export class NgIf { private _updateView() { ... if (this._thenTemplateRef) { this._thenViewRef = this._viewContainer.createEmbeddedView(this._thenTemplateRef,this._context);
createComponent
它用于使用ComponentFactory创建视图.它是由Angular编译器在模块的bootstrap属性中指定组件时创建的,因此编译器会为其生成工厂.使用此方法创建的视图称为hostview.
import { Component,ViewContainerRef,ComponentFactoryResolver,NgZone,VERSION,ViewChild } from '@angular/core'; @Component({ selector: 'hello',template: `<h1>Hello Component!</h1>`,styles: [``] }) export class HelloComponent {} @Component({ selector: 'my-app',template: ` <ng-container #vc></ng-container> `,styles: [''] }) export class AppComponent { @ViewChild('vc',{read:ViewContainerRef}) vc: ViewContainerRef; constructor(private resolver: ComponentFactoryResolver) {} ngOnInit() { const factory = this.resolver.resolveComponentFactory(HelloComponent); this.vc.createComponent(factory); } }
要了解有关主机视图和嵌入式视图之间差异的更多信息,请阅读What is the difference between a view,a host view and an embedded view