【发布时间】:2017-02-12 21:50:40
【问题描述】:
问题
我正在寻找将已知/定义的组件注入应用程序的根目录并将@Input() 选项投射到该组件上的最佳方法。
要求
这是在应用程序主体中创建模态框/工具提示等内容所必需的,这样overflow:hidden/etc 就不会扭曲或完全切断位置。
研究
我发现我可以得到ApplicationRef's 然后粗暴地向上遍历并找到ViewContainerRef。
constructor(private applicationRef: ApplicationRef) {
}
getRootViewContainerRef(): ViewContainerRef {
return this.applicationRef['_rootComponents'][0]['_hostElement'].vcRef;
}
一旦我有了它,我就可以在 ref 上调用 createComponent,例如:
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);
话虽如此,上述所有方法实际上都有效,但有时感觉有点老套。我还担心像上面那样设置输入属性的生命周期时间,因为它发生在创建之后。
重要参考文献
【问题讨论】:
-
您不能对动态添加的组件使用绑定。您的方法是目前可以从 Angular2 获得的最佳方法。我认为 Angular2 团队会尝试在这方面进行改进,但目前还不清楚什么时候可以期待它。
标签: angular angular2-components