Угловой реестр для входных компонентов - PullRequest
0 голосов
/ 19 сентября 2018

Мне нужно устройство, показывающее настраиваемую панель виджетов.Основное приложение должно предоставлять компонент панели мониторинга, который на основе конфигурации отображает виджеты в сетке.Для каждого виджета создается экземпляр контейнера виджета, который вызывает сервис, который возвращает тип компонента (то есть декорированный класс).Тип используется для разрешения фабрики его компонентов, а последний используется для создания компонента внутри 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, кто его разработал,моя служба виджетов больше не может возвращать тип компонента по заданной строке, и теперь он должен вернуть это ComponentFactory.Таким образом, он становится службой, которая должна иметь возможность извлекать список всех фабрик компонентов, загруженных в этот момент, даже из модулей, импортированных в другое место, и находить конкретный, имеющий некоторый идентификатор.Как мне этого добиться?Я пытаюсь понять, что нужно добавить в этот сервис: какой угловой сервис предоставляет список всех существующих фабрик компонентов?

1 Ответ

0 голосов
/ 19 сентября 2018

Работая с кодом, я пришел к этому хакерскому решению в моей службе распознавания виджетов:

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;
}

Я знаю, что _factories есть в службе ComponentFactoryResolver, она просто не раскрывается.Единственная общедоступная функция принимает Type <{}> в качестве аргумента, но у меня не может быть фактического класса Component, все, что у меня есть, - это имя класса, поэтому мне нужно вручную найти фабрику из списка всех известных фабрик.в угловую.

Есть ли более чистое решение?

...