我一直在使用这样的代码在我的应用程序中动态创建组件。这些组件必须支持动态输入。但现在我尝试更新到Angular 5并且不推荐使用ReflectiveInjector。如果有人知道如何帮助我重复使用Angular 5 ......我将非常感激。
import {Component, Input, ViewContainerRef, ViewChild, ReflectiveInjector, ComponentFactoryResolver} from '@angular/core';
import {
AComponent,
BComponent,
CComponent
} from './';
@Component({
selector: 'dynamic-component',
entryComponents: [
AComponent,
BComponent,
CComponent
],
template: `
<div #dynamicComponentContainer></div>
`
})
export class DynamicComponent {
currentComponent = null;
@ViewChild('dynamicPriceItemComponentContainer', { read: ViewContainerRef }) dynamicComponentContainer: ViewContainerRef;
@Input() set componentData( data: { component: any, inputs: any }) {
if (!data) {
return;
}
let inputProviders = Object.keys(data.inputs).map((inputName) => {
return { provide: inputName, useValue: data.inputs[inputName] };
});
let resolvedInputs = ReflectiveInjector.resolve(inputProviders);
let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.dynamicPriceItemComponentContainer.parentInjector);
let factory = this.resolver.resolveComponentFactory(data.component);
let component = factory.create(injector);
this.dynamicComponentContainer.insert(component.hostView);
if (this.currentComponent) {
this.currentComponent.destroy();
}
this.currentComponent = component;
}
constructor(private resolver: ComponentFactoryResolver) {
}
}
答案 0 :(得分:1)
这可以提供一些线索。
constructor(private renderer: Renderer2,
private viewContainerRef: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver) {
}
private createdDynamicComponent(): void {
const factory = this.componentFactoryResolver.resolveComponentFactory(MyComponent);
const createdComponentComponent = this.viewContainerRef.createComponent(factory);
this.renderer.appendChild('element where you want append', createdComponentComponent.location.nativeElement);
}
答案 1 :(得分:1)
您需要Injector.create
而不是ReflectiveInjector
@Input()
set dynamicContent(dc: { component: any; attribute: any; payload: any }) {
if (!dc) {
return;
}
const injector = Injector.create({
providers: [
{
provide: dc.attribute,
useValue: dc.payload
}
],
parent: this.dynamicComponentContainer.parentInjector
});
const factory = this.resolver.resolveComponentFactory(dc.component);
const component = factory.create(injector);
this.dynamicComponentContainer.insert(component.hostView);
}
当您在实际动态子组件中注入输入名称时,您当然需要解决Reflection弃用问题。 关键是要避免注入字符串:
constructor(@Inject(LabelComponentAttributes) public ca: LabelComponentAttributes) {
super();
this.setCurrentStyles();
this.setCurrentClasses();
}
将所有输入分组并注入该类。 不要将它们分组到界面中,因为它们仅在运行时以打字稿形式提供。
欢呼声
答案 2 :(得分:0)
将来可能会使用NgComponentOutlet
指令。看一下这个issue。同时你可以使用ng-dynamic-component?