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

Angular8中NgModuleFactoryLoader.load传入Function类型loadChildren报错如何解决

问题原因

Angular 8 开始官方弃用了字符串格式的loadChildren配置,改为动态导入的函数写法。你用到的NgModuleFactoryLoader.load()是专为旧版字符串路径设计的API,仅接收字符串类型参数,因此传入Function会抛出类型不匹配错误,且该API从Angular 8开始已标记为弃用,后续版本会逐步移除。

修复步骤

1. 调整接口类型定义

不要用宽泛的Function定义loadChildren,直接使用Angular官方提供的LoadChildren类型,保证类型准确性:

import { LoadChildren } from '@angular/router';

export interface DynamicComponentManifest {
  componentId: string;
  path: string;
  loadChildren: LoadChildren;
}

2. 替换加载逻辑

无需再使用NgModuleFactoryLoader,直接执行loadChildren函数即可获取目标模块,同时注入Compiler处理模块编译逻辑:
首先在服务的构造函数中注入Compiler,替换掉原来的NgModuleFactoryLoader注入:

import { Compiler } from '@angular/core';

constructor(
  private injector: Injector,
  private compiler: Compiler // 新增注入Compiler
  // 移除原来的NgModuleFactoryLoader注入
) {}

然后修改getComponentFactory的加载逻辑:

import { from, of, throwError, mergeMap } from 'rxjs';
import { NgModuleFactory, Type, ComponentFactory, Injector } from '@angular/core';

public getComponentFactory<T>(
  componentId: string,
  injector?: Injector,
): Observable<ComponentFactory<T>> {
  const manifest = this.manifests.find(m => m.componentId === componentId);
  if (!manifest) {
    return throwError(`DynamicComponentLoader: Unknown componentId "${componentId}"`);
  }

  // 直接执行loadChildren函数,将返回的Promise转为Observable
  return from(Promise.resolve(manifest.loadChildren())).pipe(
    mergeMap(moduleOrFactory => {
      let ngModuleFactory: NgModuleFactory<any>;
      // 兼容两种返回格式:ViewEngine下返回NgModuleFactory,Ivy下返回模块类
      if (moduleOrFactory instanceof NgModuleFactory) {
        ngModuleFactory = moduleOrFactory;
      } else {
        ngModuleFactory = this.compiler.compileModuleSync(moduleOrFactory as Type<any>);
      }
      
      const moduleRef = ngModuleFactory.create(injector || this.injector);
      const dynamicComponentType = moduleRef.injector.get(DYNAMIC_COMPONENT, null);
      if (!dynamicComponentType) {
        throw new Error(
          `DynamicComponentLoader: Dynamic module for componentId "${componentId}" does not contain DYNAMIC_COMPONENT as a provider.`
        );
      }
      return of(moduleRef.componentFactoryResolver.resolveComponentFactory<T>(dynamicComponentType));
    })
  );
}

3. 保证loadChildren配置符合规范

你的manifest配置中loadChildren需要按照Angular 8+的动态导入写法:

const manifests: DynamicComponentManifest[] = [
  {
    componentId: 'your-component-id',
    path: 'your-path',
    loadChildren: () => import('./path/to/your.module').then(m => m.YourCustomModule)
  }
];

内容的提问来源于stack exchange,提问作者ShivamPatel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:06:03