角度 9 - 生产模式下的模块延迟加载不起作用



我有一个库项目,其中我有一个模块和几个组件。在我的实际应用程序中,我想动态加载库模块并渲染组件。在开发模式下一切正常,但是当我使用生产模式运行我的应用程序时,总是从工厂(使用 moduleFactory.componentFactory(获取空组件数组。下面是我的代码。任何人都可以帮我解决这个问题。我正在使用 Angular 9.1.0。

import { Injectable, Type, Compiler, Injector, ComponentFactory, NgModuleFactory } from '@angular/core';
import { Observable, of } from 'rxjs';
import { delay, tap } from 'rxjs/operators';
import { ApptorCustomCompHostComponent } from '@apptor/corecomps';
@Injectable({
providedIn: 'root',
})
export class LazyLoaderService {
private modules: Map<string, any> = new Map();
private componentRegistry: any[] = [
{ type: "textbox", className: "ApptorCorecompsWrapperComponent", moduleName: "ApptorCorecompsModule" }
];
constructor(private compiler: Compiler, private injector: Injector) {
}
public async getComponentFactory(componentType: string): Promise<ComponentFactory<any>> {
let compInfo = this.componentRegistry.find(c => c.type === componentType);
if (compInfo) {
let factories = this.modules.get(compInfo.moduleName);
if (!factories) {
await this.loadModule(compInfo.moduleName);
factories = this.modules.get(compInfo.moduleName);
}
let componentFactory = factories.find(f => compInfo.className === f.componentType.name);
return componentFactory;
}
return null;
}

async loadModule(moduleName: string) {
switch (moduleName) {
case 'ApptorCorecompsModule':
this.loadModuleInternal(moduleName, await import('@apptor/corecomps').then(m => m[moduleName]));
break;
case 'lazy':
this.loadModuleInternal(moduleName, await import('@apptor/corecomps').then(m => m[moduleName]));
break;
}
}
private loadModuleInternal(moduleName: string, moduleType: Type<any>) {
const moduleFactory = this.compiler.compileModuleAndAllComponentsSync(moduleType);
const componentFactories = moduleFactory.componentFactories;
this.modules.set(moduleName, componentFactories);
console.log("module loaded is: ", moduleName);
}
}

我们使其工作如下。希望这可以帮助其他人。

import { Injectable, Compiler, Injector, ComponentFactory, ComponentFactoryResolver } from '@angular/core';
import { ReplaySubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class LazyLoaderService {
private modules: Map<string, ReplaySubject<any>> = new Map();
private componentRegistry: any[] = [
{ type: "textbox", className: "ApptorCorecompsWrapperComponent", moduleName: "ApptorCorecompsModule" }
];
constructor(private compiler: Compiler, private injector: Injector,
private factoryResolver: ComponentFactoryResolver) {
}
public async getComponentFactory(componentType: string): Promise<ComponentFactory<any>> {
//this.loadComponent();
const compInfo = this.componentRegistry.find(c => c.type === componentType);
if (!compInfo)
throw new Error("Invalid component type:" + componentType);
let modSubject = this.modules.get(compInfo.moduleName);
if (!modSubject) {
modSubject = this.loadModule(compInfo.moduleName);
}
let ret: Promise<ComponentFactory<any>> = new Promise((resolve, reject) => {
modSubject.subscribe(async (moduleRef) => {
//await this.compileModule(mod);
const compType = moduleRef.instance.controls[compInfo.className];
if (compType) {
let componentFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(compType);
// let componentFactory =  this.factoryResolver.resolveComponentFactory(compType);
resolve(componentFactory);
} else {
console.error("Component :" + compInfo.className + " not found");
reject(null);
}
});
});
return ret;

}
public loadModule(moduleName): ReplaySubject<any> {
//let mod:any = null;
let mod: ReplaySubject<any> = new ReplaySubject();
switch (moduleName) {
case 'ApptorCorecompsModule':
import('@apptor/corecomps').then(async m => {
let mm = m[moduleName]
mm = await this.compileModule(mm);
mod.next(mm);
//return mm; 
});
break;
}
if (mod) {
this.modules.set(moduleName, mod);
return mod;
}
else {
console.error("Failed to load module: " + moduleName);
throw new Error("Failed to load module: " + moduleName);
}
}
private async compileModule(module: any) {
let ret: Promise<any> = new Promise((resolve, reject) => {
this.compiler.compileModuleAsync(module).then(factory => {
const moduleRef = factory.create(this.injector);
resolve(moduleRef);
});
});
return ret;
}
}

最新更新