Angular中如何获取当前模块(如AppModule)的NgModuleRef以实现组件动态创建?
Angular动态创建组件时获取当前模块NgModuleRef的方法
当然可行啦!在Angular开发场景中,完全可以获取当前模块对应的NgModuleRef,用来在动态创建组件时传入指定模块上下文,下面给你几种实用的实现方式:
方法一:通过ApplicationRef获取根模块的NgModuleRef
如果你的组件是在根模块(比如你定义的AppModule)下运行的,直接注入ApplicationRef就能拿到根模块的引用:
import { Component, ViewContainerRef, ApplicationRef, NgModuleRef } from '@angular/core'; import { HeroJobAdComponent } from './hero-job-ad.component'; @Component({ selector: 'app-ad-banner', template: `<ng-template adHost></ng-template>` }) export class AdBannerComponent { constructor( private viewContainerRef: ViewContainerRef, private appRef: ApplicationRef ) {} loadAd() { // 获取根模块的NgModuleRef const myModuleRef = this.appRef.injector.get(NgModuleRef); // 动态创建组件时传入 this.viewContainerRef.createComponent(HeroJobAdComponent, { ngModuleRef: myModuleRef }); } }
方法二:直接注入当前模块的NgModuleRef
如果你的组件属于特定模块(比如AppModule),可以在组件构造函数里直接注入NgModuleRef<AppModule>,Angular会自动提供当前模块的实例:
import { Component, ViewContainerRef, NgModuleRef } from '@angular/core'; import { AppModule } from './app.module'; import { HeroProfileComponent } from './hero-profile.component'; @Component({ selector: 'app-ad-banner', template: `<ng-template adHost></ng-template>` }) export class AdBannerComponent { constructor( private viewContainerRef: ViewContainerRef, private myModuleRef: NgModuleRef<AppModule> ) {} loadAd() { // 直接使用注入的模块引用 this.viewContainerRef.createComponent(HeroProfileComponent, { ngModuleRef: this.myModuleRef }); } }
方法三:通过组件的Injector间接获取
如果你的场景比较复杂,也可以利用组件自身的Injector来获取NgModuleRef,只要当前组件的注入器属于目标模块就行:
import { Component, ViewContainerRef, Injector, NgModuleRef } from '@angular/core'; import { HeroJobAdComponent } from './hero-job-ad.component'; @Component({ selector: 'app-ad-banner', template: `<ng-template adHost></ng-template>` }) export class AdBannerComponent { constructor( private viewContainerRef: ViewContainerRef, private injector: Injector ) {} loadAd() { const myModuleRef = this.injector.get(NgModuleRef); this.viewContainerRef.createComponent(HeroJobAdComponent, { ngModuleRef: myModuleRef }); } }
额外注意事项
- 要是你在特性模块里动态创建组件,上述方法拿到的会是当前特性模块的
NgModuleRef;如果需要根模块的,优先用方法一。 - Angular 9及以后的版本(Ivy编译器)不需要手动把动态组件加入
entryComponents,但要确保组件已经在目标模块的declarations里声明过,不然会创建失败哦。
内容的提问来源于stack exchange,提问作者jake
相关产品推荐
相关产品推荐

