迁移到Angular v.5.2.9后发现了弃用消息:
不推荐使用ReflectiveInjector:从v5开始 - 缓慢并带来大量代码,改为使用
Injector.create
。
在Angular v5之前,我创建了这样的动态组件:
// Old API with ReflectiveInjector
createWithReflectiveInjector() {
// Inputs need to be in the following format to be resolved properly
const resolvedInputs = ReflectiveInjector.resolve([
{ provide: "options", useValue: this.data }
]);
// Clear the template before inserting new one
this.dynamicComponentContainer.clear();
// We create an injector out of the data we want to pass down and this components injector
const injector = ReflectiveInjector.fromResolvedProviders(
resolvedInputs,
this.dynamicComponentContainer.parentInjector
);
// We create a factory out of the component we want to create
const factory = this.resolver.resolveComponentFactory(CounterWithInject);
// We create the component using the factory and the injector
const component = factory.create(injector);
// Subscribe to Output events:
component.instance.resetCounter.subscribe(() => {
this.data.count = 0;
});
// We insert the component into the dom container
this.dynamicComponentContainer.insert(component.hostView);
}
我已经使用 Injector.create()重构了更新的API:
createWithInjector() {
const inputs = [{ provide: "options", useValue: this.data }];
// Clear the template before inserting new one
this.dynamicComponentContainer2.clear();
const injector = Injector.create({
providers: inputs,
parent: this.dynamicComponentContainer2.parentInjector
});
// We create a factory out of the component we want to create
const factory = this.resolver.resolveComponentFactory(CounterWithInput);
// Destroy the previously created component
if (this.componentRef) {
this.componentRef.destroy();
}
this.componentRef = this.dynamicComponentContainer2.createComponent(
factory, 0, injector);
// We insert the component into the dom container
this.dynamicComponentContainer2.insert(this.componentRef.hostView);
this.componentRef.instance.resetCounter.subscribe(() => {
this.data.count = 0;
});
}
即使在切换到新的Injector API之后,它实际上也是相同的代码。
我的问题是:
1)也许我在文档中遗漏了一些东西,并且在Angular v5 +中可以大大简化创建动态组件?
2)注意到在official doc输入数据中提供了组件的扩展实例,如下所示:
let componentRef = viewContainerRef.createComponent(componentFactory);
(<AdComponent>componentRef.instance).data = adItem.data;
为动态组件提供道具的首选方式:
与提供商:
const inputs = [{ provide: "options", useValue: { count: 0} }];
const injector = Injector.create({
providers: inputs,
parent: this.dynamicComponentContainer2.parentInjector
});
并阅读组件中注入的道具:
...
ngOnInit() {
this.options = this.injector.get("options") || {};
}
实例扩展:
// Define input data
this.componentRef.instance.data = { count: 0 };
并在组件中获取 @Input():
export class CounterWithInput implements OnInit {
@Input() data: any;
}
使用方法进行现场演示:link