入口组件的 Angular 注册表
Posted
技术标签:
【中文标题】入口组件的 Angular 注册表【英文标题】:Angular registry for entry components 【发布时间】:2019-02-23 16:08:39 【问题描述】:我需要一个组件来显示可配置的小部件仪表板。 主应用程序应提供一个仪表板组件,该组件基于配置在网格中显示小部件。 对于每个小部件,都会实例化一个小部件容器组件,该组件调用一个返回组件类型(即装饰类)的服务。该类型用于解析其组件工厂,后者用于在小部件容器内的 ViewComponentRef 内创建组件。
widget-container.html:
<div class="placeholder" #target></div>
<div class="loader">
<mat-spinner [diameter]="50"></mat-spinner>
</div>
小部件容器.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。因此,它成为一项服务,必须能够检索在该点加载的所有组件工厂的列表,即使是从其他地方导入的模块,并找到给定某种标识符的特定工厂。 我怎样才能做到这一点?我试图了解在此服务中注入了什么:哪个 Angular 服务提供了所有现有组件工厂的列表?
【问题讨论】:
【参考方案1】:摆弄代码,我在我的小部件解析器服务中找到了这个 hacky 解决方案:
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 === `$componentNameComponent`)
ret = f;
found = true;
);
return ret;
我知道 _factories 存在于 ComponentFactoryResolver 服务中,它只是没有暴露。唯一的公共函数将 Type 作为参数,但我没有实际的 Component 类,我只有类的名称,所以我需要从所有已知工厂列表中手动查找工厂到角度。
有更清洁的解决方案吗?
【讨论】:
澄清一下,自 Angular 9 以来,此解决方案不再有效。据我所知,在不手动维护字符串的情况下,仍然没有简单的方法可以从字符串动态创建组件->类型映射.有关此主题的讨论,请参阅 github.com/angular/angular/issues/24360。以上是关于入口组件的 Angular 注册表的主要内容,如果未能解决你的问题,请参考以下文章
Angular动态注册组件(controller,service...)
Angular & ag-grid:无法使用 frameworkComponents 注册框架组件
利用angular4和nodejs-express构建一个简单的网站—用户注册之ReactiveForm