如何动态的插入一个组件

2017-07-04  本文已影响52人  JamesSawyer

主要用到的APIs有:

示例

动态的创建一个AlertComponent组件

AlertComponnet:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-selector',
  template: `
    <h1> alert {{ info }}</h1>
  `
})
export class AlertComponent {
  @Input() info: string = 'information'; // 输入属性
}

AppComponent

import {
  Component,
  ComponentRef,
  ComponentFactory,
  ComponentFactoryResolver,
  ViewChild,
  ViewContainerRef,
  OnDestroy
} from '@angular/core';
import { AlertComponent } from './alert.component';

@Component({
  selector: 'app-root',
  template: `
    <div>
      <ng-template #alertContainer></ng-template> // 这里放动态生产的AlertComponent组件
      <button (click)="createAlert('success')">创建成功alert组件</button>
      <button (click)="createAlert('warning')">创建警告alert组件</button>
    </div>
  `
})
export class AppComponent implements OnDestroy {
  // 查找到 <ng-template> 元素
  // { read: ViewContainerRef }) 表示将这个元素(<ng-template>)当作视图容器的引用
  @ViewChild('alertContainer', { read: ViewContainerRef }) container: ViewContainerRef; 
  componentRef: ComponentRef<AlertComponent>; // 表示对AlertComponent组件的引用

  constructor(
    // ComponentFactoryResolver 暴露一个重要的方法 'resolveComponentFactory'
    // 'resolveComponentFactory()' 接收一个组件当作参数, 返回一个 ComponentFactory
    private resolver: ComponentFactoryResolver // 注入这个服务
  ){}

  createAlert(msg) {
   this.container.clear(); // 表示一上来先清空视图容器
    // 创建组件工厂
   const factory: ComponentFactory<AlertComponent> = this.resolver.resolveComponentFactory(AlertComponent);
    // 动态的创建该组件
    // createComponent() 内部其实是调用factory内部的create()方法
    this.componentRef = this.container.createComponent(factory);
    // this.componentRef.instance 表示 组件实例
    this.componentRef.instance.info = msg;
  }

  ngOnDestroy(): void {
    this.componentRef.destroy(); // 最后别忘记了销毁该组件
  }
}

上面的过程详解:

// 这个表示将容器清空
// 如果不清空的话,创建的组件将不停的添加到视图容器中(如果这是你想要的效果,可以不必调用这个方法)
this.container.clear(); 

最后将动态插入的组件添加到 entryComponents 中:

import { AppComponent } from './app.component';
import { AlertComponent } from './components/alert/alert.component';
@NgModule({
  declarations: [
    AppComponent,
    AlertComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  entryComponents: [AlertComponent], // 动态创建的组件
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
}

最后效果如图:


动态创建组件.png

参考文章:

上一篇 下一篇

猜你喜欢

热点阅读