我需要安装一个组件,该组件显示可配置的小部件仪表板。 主应用程序应提供一个仪表板组件,该组件基于配置在网格中显示小部件。 对于每个窗口小部件,将实例化窗口小部件容器组件,该组件将调用返回组件类型(即装饰类)的服务。该类型用于解析其组件工厂,后者用于在小部件容器内的ViewComponentRef内创建组件。
widget-container.html:
<div class="placeholder" #target></div>
<div class="loader">
<mat-spinner [diameter]="50"></mat-spinner>
</div>
widget-container.ts:
constructor(
private readonly _el: ElementRef,
private readonly _renderer: Renderer2,
private _componentFactoryResolver: ComponentFactoryResolver,
private readonly _widgetService: WidgetService
) {}
ngOnInit(): void {
const componentClass = this._widgetService.getWidget(this.widgetDefinition.componentName);
const factory = this._componentFactoryResolver.resolveComponentFactory(componentClass);
this._componentRef = this._viewContainer.createComponent(factory);
const newItem: WidgetBase = this._componentRef.instance;
}
现在,该应用程序需要使用可插入其他功能的模块进行扩展。假设这些模块已作为npm插件包导入到应用中:
main-app.module.ts:
import { Plugin1Module } from "@mycompany/plugin1";
[...]
@NgModule({
imports: [..., Plugin1Module], [...]
})
export class MainAppModule {}
因此,由于Plugin1Module是由谁开发的AOT编译的,所以我的窗口小部件服务无法再返回给定字符串的Component Type,因此现在需要返回的是ComponentFactory。因此,它成为一项服务,必须能够检索到该点加载的所有组件工厂的列表,即使是从其他位置导入的模块中,也可以找到给定某种标识符的特定工厂。 我该如何实现?我试图了解要在此服务中注入什么:哪个角度服务提供了所有现有组件工厂的列表?
答案 0 :(得分:0)
摆弄代码,我在小部件解析器服务中找到了这个骇人听闻的解决方案:
getWidgetComponentFactory(componentName: string): ComponentFactory<WidgetBase> {
let ret: ComponentFactory<WidgetBase> = null;
let found = false;
(this._resolver as any)._factories.forEach((f: ComponentFactory<any>) => {
if (found) {
return;
}
if (f.componentType.name === `${componentName}Component`) {
ret = f;
found = true;
}
});
return ret;
}
我知道ComponentFactoryResolver服务上有_factories,只是没有公开。唯一的公共函数将Type <{}>作为参数,但是我没有实际的Component类,我只拥有类的名称,因此我需要从所有已知工厂的列表中手动找到工厂倾斜。
有更清洁的解决方案吗?