You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 04:36:08