Fork Me On Github

angular 12 动态生成组件

需求

在页面中生成一个确认弹窗

代码

第一步,获取需要的工具

export class DialogService {

    constructor(
        private resolver: ComponentFactoryResolver,
        private applicationRef: ApplicationRef,
        private injector: Injector, 
        @Inject(DOCUMENT) private document: Document,
    ) { }


}

第二步,实现动态生成组件

component 为组件的类名

const dialogFactory = this.resolver.resolveComponentFactory(component);
const dialogRef = dialogFactory.create(this.injector);
// 正式添加到程序和添加到页面上,才能显示
this.applicationRef.attachView(dialogRef.hostView);
this.document.body.appendChild(dialogRef.location.nativeElement);

// dialogRef.instance 就是组件的实例 

第三步,移除组件

this.applicationRef.detachView(dialogRef.hostView);
this.document.body.removeChild(dialogRef.location.nativeElement);

如果需要在组件初始化,自动注入值或传值,则需要自定义 injector

import { InjectFlags, Injector, ProviderToken } from '@angular/core';

// 这个类是传值的载体
export class DialogPackage<T = any> {
    constructor(
        public data: T,
        public dialogId: any,
    ) {
    }
}

// 这是自定义的注射器
export class DialogInjector<T> implements Injector {

    constructor(
        private data: DialogPackage,
        private parentInjector: Injector
      ) {}

    get<T>(token: ProviderToken<T>, notFoundValue?: T, flags?: InjectFlags): T;
    get(token: any, notFoundValue?: any);
    get(token: any, notFoundValue?: any, flags?: any): any {
        if (token === DialogPackage) {
            return this.data;
          }
          return this.parentInjector.get<T>(token, notFoundValue, flags);
    }

}

第二步需要修改

const dialogFactory = this.resolver.resolveComponentFactory(component);
// 这里的option 可以是任何值
const dialogInjector = new DialogInjector(new DialogPackage(option, dialogId), this.injector);
const dialogRef = dialogFactory.create(dialogInjector);
// 正式添加到程序和添加到页面上,才能显示
this.applicationRef.attachView(dialogRef.hostView);
this.document.body.appendChild(dialogRef.location.nativeElement);

// dialogRef.instance 就是组件的实例 

在组件中接收值

export class DialogConfirmComponent {

    constructor(
        private data: DialogPackage<DialogConfirmOption>,
        private service: DialogService,
    ) {

    }
}
Click here to view
Tags: angular
0 299 0
使用ng-template 显示tree结构数据
使用 ViewContainerRef.createComponent 替代 ComponentFactoryResolver
angular 12使用 KaTex 显示 AsciiMath 格式的公式
ng-deep 使用
angular 12 动画执行完成事件