Angular13如何从JSON文件读取组件名并动态加载组件列表
Angular 13 动态加载JSON配置对应组件实现方案
实现步骤
- 第一步:准备配置文件与基础依赖
将你的组件列表配置存为src/assets/component-config.json,内容如下:
打开[ { "name": "Component1" }, { "name": "Component2" } ]app.module.ts,导入HttpClientModule用于读取静态JSON文件:import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ // 其他导入... HttpClientModule ] }) export class AppModule { } - 第二步:创建动态组件锚点指令
新建src/app/component-host.directive.ts,用于标记动态组件的插入位置:
同时将该指令加入import { Directive, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[appComponentHost]' }) export class ComponentHostDirective { constructor(public viewContainerRef: ViewContainerRef) { } }AppModule的declarations数组中。 - 第三步:维护组件映射表与核心逻辑
打开app.component.ts,编写JSON读取、组件创建逻辑:import { Component, OnInit, ViewChildren, QueryList, Type } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { ComponentHostDirective } from './component-host.directive'; // 导入你需要动态加载的组件 import { Component1 } from './component1/component1.component'; import { Component2 } from './component2/component2.component'; // 组件名与实际组件类的映射表,必须手动维护 const COMPONENT_MAP: Record<string, Type<any>> = { 'Component1': Component1, 'Component2': Component2 } @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { componentListToLoad: Array<{name: string}> = []; // 查询所有动态组件锚点 @ViewChildren(ComponentHostDirective) componentHosts!: QueryList<ComponentHostDirective>; constructor(private http: HttpClient) {} ngOnInit(): void { // 读取JSON配置 this.http.get<Array<{name: string}>>('/assets/component-config.json').subscribe(res => { this.componentListToLoad = res; // 等待DOM渲染完成后加载组件 setTimeout(() => this.loadComponents(), 0); }) } private loadComponents(): void { this.componentListToLoad.forEach((item, index) => { const host = this.componentHosts.get(index); if (!host || !COMPONENT_MAP[item.name]) return; // 清空容器避免重复加载 host.viewContainerRef.clear(); // 创建组件 const componentRef = host.viewContainerRef.createComponent(COMPONENT_MAP[item.name]); // 如果需要给组件传参/监听事件,可通过componentRef.instance操作 // 示例:componentRef.instance.title = '动态传入的标题'; }) } } - 第四步:编写模板代码
替换你原有app.component.html的循环代码即可:<div *ngFor="let item of componentListToLoad"> <ng-container appComponentHost></ng-container> </div>
注意事项
- 所有需要动态加载的组件必须在对应模块的
declarations数组中声明,Angular 13+ 已废弃entryComponents配置,无需额外添加。 - 生产环境打包会自动压缩类名,禁止通过类的
name属性动态匹配组件,必须手动维护COMPONENT_MAP映射表避免生产环境报错。 - 若组件需要支持输入输出参数,可在
createComponent后通过componentRef.instance进行赋值和事件订阅。
内容的提问来源于stack exchange,提问作者deszok
相关产品推荐
相关产品推荐

