Вопрос
Я ищу наилучший подход для ввода известного/определенного компонента в корень приложения и проектирования @Input()
параметров на этот компонент.
Требование
Это необходимо для создания таких вещей, как модалы/всплывающие подсказки в теле приложения, так что overflow:hidden
/etc не будет искажать позицию или полностью отключить ее.
Исследование
Я обнаружил, что могу получить ApplicationRef
, а затем взломать его вверх и найти ViewContainerRef
.
constructor(private applicationRef: ApplicationRef) {
}
getRootViewContainerRef(): ViewContainerRef {
return this.applicationRef['_rootComponents'][0]['_hostElement'].vcRef;
}
как только у меня есть, то я могу позвонить createComponent
в поле ref:
appendNextToLocation<T>(componentClass: Type<T>, location: ViewContainerRef): ComponentRef<T> {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentClass);
const parentInjector = location.parentInjector;
return location.createComponent(componentFactory, location.length, parentInjector);
}
но теперь я создал компонент, но ни одно из моих свойств Input
не выполняется. Чтобы добиться этого, мне приходится вручную переходить по моим параметрам и устанавливать их в результате экземпляра appendNextToLocation
, например:
const props = Object.getOwnPropertyNames(options);
for(const prop of props) {
component.instance[prop] = options[prop];
}
Теперь я понимаю, что вы могли бы сделать DI, чтобы вводить параметры, но это делает его не пригодным для повторного использования при попытке использовать в качестве обычного компонента. Вот как это выглядит для справки:
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(ComponentClass);
let parentInjector = location.parentInjector;
let providers = ReflectiveInjector.resolve([
{ provide: ComponentOptionsClass, useValue: options }
]);
childInjector = ReflectiveInjector.fromResolvedProviders(providers, parentInjector);
return location.createComponent(componentFactory, location.length, childInjector);
все, что сказано, все вышеизложенное действительно работает, но время от времени оно бывает немного взломанным. Я также беспокоюсь о сроках жизненного цикла установки параметров ввода, как указано выше, так как это происходит после его создания.