所以我试图创建一个模块,它会占用大量组件并动态加载它们,但不会弄乱AoT。事实证明这是一个挑战,但除了一件事之外,我真的很接近。如何检索存储在ComponentFactory中的所有组件?
在mij app.module.ts
中,我将一组组件传递给动态加载模块的forRoot():
imports: [
DynamicLoadModule.forRoot(dynamicComponents),
]
在我的dynamic-load.module.ts
中,我将所有这些内容添加到Angular2 ComponentFactory:
static forRoot(components: any[]) {
return {
ngModule: DynamicLoadModule,
providers: [{
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
useValue: components,
multi: true,
}, {
provide: DynamicLoadService,
useValue: new DynamicLoadService(components)
}]
};
}
现在的问题在于DynamicLoadService
,它正在搞乱AoT。我已尝试过记录的导出功能方式,但这并没有解决问题,因为这样我无法将components
作为参数传递给服务。因此the Angular documentation中的以下内容无法解决我的问题:
let heroServiceFactory = (logger: Logger, userService: UserService) => {
return new HeroService(logger, userService.user.isAuthorized);
};
export let heroServiceProvider =
{ provide: HeroService,
useFactory: heroServiceFactory,
deps: [Logger, UserService]
};
然后我尝试使用dynamic-load.module
将组件传递给我的OpaqueToken
,这也没有帮助,因为我最多只有未编译的组件,而且我的模块失去了很多灵活性。
所以我得出的结论是,如果我需要ComponentFactory
中所有组件的数组,我只需要一种方法来检索所有组件。
所以,我现在使用ComponentFactoryResolver
根据我需要的名称获取一个模板,或者至少获得工厂中所有组件的名称。
if (selectedComponent !== '') {
if (typeof this.currentComponent !== 'undefined') { this.currentComponent.destroy(); }
const components = this.dynamicLoadService.getComponents(), // --> instead of getting a list of available components through this service which needs the factory that blocks AoT, I should just be able to retrieve all available components from the ComponentFactory
component: any = components.find((x) => x.name.toLowerCase().indexOf(selectedComponent) > -1),
compFactory = this.cfr.resolveComponentFactory(component);
this.currentComponent = this.vcr.createComponent(compFactory);
this.currentComponent.instance.data = this.componentData;
}
答案 0 :(得分:2)
修改强> 所以第一个答案并没有完全解决问题,但另一个有帮助的人能够通过Angular Github帮助我解决问题。
最后,我的代码如下所示:
import { NgModule, ANALYZE_FOR_ENTRY_COMPONENTS, Inject } from '@angular/core';
import { DynamicLoadService } from './dynamic-load.service';
import { DynamicLoadComponent } from './dynamic-load.component';
export function DynamicLoadFactory(cmps) {
return new DynamicLoadService(cmps);
}
@NgModule({
declarations: [
DynamicLoadComponent
],
exports: [
DynamicLoadComponent
]
})
export class DynamicLoadModule {
static forRoot(components: any[]) {
return {
ngModule: DynamicLoadModule,
providers: [{
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
useValue: components,
multi: true
},
{
provide: 'ENTRIES',
useValue: components
},
{
provide: DynamicLoadService,
useFactory: DynamicLoadFactory,
deps: [[new Inject('ENTRIES')]]
}]
};
}
}
正如我所指出的那样ANALYZE_FOR_ENTRY_COMPONENTS
不是依赖注入树的一部分(查找源here)。因此,上述解决方法可以解决该问题。
所以答案是在Angular Github上给我一个非常有帮助的人。
有人向我建议我应该
只需将
即可ANALYZE_FOR_ENTRY_COMPONENTS
注入DynamicLoadService
现在看起来像这样:
export function DynamicLoadFactory(cmps) {
return new DynamicLoadService(cmps);
}
export class DynamicLoadModule {
static forRoot(components: any[]) {
return {
ngModule: DynamicLoadModule,
providers: [{
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
useValue: components,
multi: true,
}, {
provide: DynamicLoadService,
useFactory: DynamicLoadFactory,
deps: [new Inject(ANALYZE_FOR_ENTRY_COMPONENTS)]
}]
};
}
}