How to load component dynamically using component name in angular2?

后端 未结 5 1951
鱼传尺愫
鱼传尺愫 2020-11-29 03:58

I am currently loading angular components dynamically in my application using following code.

export class WizardTabCo         


        
5条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-29 04:51

    I looked far and wide for solution that satisfies Angular 9 requirements for dynamically loaded modules and I came up with this

    import { 
        ComponentFactory, 
        Injectable, 
        Injector, 
        ɵcreateInjector as createInjector,
        ComponentFactoryResolver,
        Type
    } from '@angular/core';
    
    export class DynamicLoadedModule {
        public exportedComponents: Type[];
    
        constructor(
            private resolver: ComponentFactoryResolver
        ) {
        }
    
        public createComponentFactory(componentName: string): ComponentFactory {
            const component = (this.exportedComponents || [])
                .find((componentRef) => componentRef.name === componentName);          
    
            return this.resolver.resolveComponentFactory(component);
        }
    }
    
    @NgModule({
        declarations: [LazyComponent],
        imports: [CommonModule]
    })
    export class LazyModule extends DynamicLoadedModule {
        constructor(
            resolver: ComponentFactoryResolver
        ) {
            super(resolver);
        }
        
    }
    
    
    @Injectable({ providedIn: 'root' })
    export class LazyLoadUtilsService {
        constructor(
            private injector: Injector
        ) {
        }
    
        public getComponentFactory(component: string, module: any): ComponentFactory {
            const injector = createInjector(module, this.injector);
            const sourceModule: DynamicLoadedModule = injector.get(module);
    
            if (!sourceModule?.createComponentFactory) {
                throw new Error('createFactory not defined in module');
            }
    
            return sourceModule.createComponentFactory(component);
        }
    }
    

    Usage

    async getComponentFactory(): Promise> {
        const modules = await import('./relative/path/lazy.module');
        const nameOfModuleClass = 'LazyModule';
        const nameOfComponentClass = 'LazyComponent';
        return this.lazyLoadUtils.getComponentFactory(
            nameOfComponentClass ,
            modules[nameOfModuleClass]
        );
    }
    

提交回复
热议问题