Angular中createEmbeddedView和createComponent之间的区别是什么

Bla*_*aze 10 angular

我在createEmbeddedView和createComponent的用例之间感到困惑,即什么时候使用哪一个.请提出一些案例,告诉他们在"动态创建场景"中使用其中任何一个的合适设置

Max*_*kyi 30

请参阅此关于DOM操作的研讨会或阅读使用Angular中的DOM:意外后果和优化技术,其中我将通过示例解释其中的差异.

这两种方法都用于动态地将内容添加到组件视图(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>
}
Run Code Online (Sandbox Code Playgroud)

要了解有关操纵DOM的更多信息,请阅读使用ViewContainerRef探索Angular DOM操作技术.

createEmbeddedView

它用于使用TemplateRef创建视图.TemplateRef是由Angular编译器ng-template在组件html中遇到标记时创建的.使用此方法创建的视图称为embedded view.

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

Stackblitz演示

所有结构指令都使用这种方法*ngIf,*ngFor因为它们都是包装的ng-template.例如,对于*ngIf代码:

<div *ngIf="data">{{name}}</div>
Run Code Online (Sandbox Code Playgroud)

变成了

<ng-template ngIf="data">
   <div>{{name}}</div>
Run Code Online (Sandbox Code Playgroud)

ngIf指令在createEmbeddedView内部使用:

@Directive({selector: '[ngIf]'})
export class NgIf {
    private _updateView() {
       ...
       if (this._thenTemplateRef) {
           this._thenViewRef =
               this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
Run Code Online (Sandbox Code Playgroud)

createComponent

它用于使用ComponentFactory创建视图.当您bootstrap在模块的属性中指定组件时,它由Angular编译器创建,因此编译器为其生成工厂.使用此方法创建的视图称为a 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

Stackblitz演示.

要了解有关主机视图和嵌入式视图之间差异的更多信息,请参阅视图,主机视图和嵌入式视图之间的区别