如何动态地将NG_VALUE_ACCESSOR组件添加到反应形式? [英] How to dynamically add NG_VALUE_ACCESSOR component to reactive form?
问题描述
我们想使用带有ComponentFactoryResolver
和ViewContainerRef
的自定义指令将NG_VALUE_ACCESSOR
组件动态添加到反应形式.问题在于我们无法为动态添加的组件分配formControlName,也无法从组件获取访问器值.
We want to dynamically add NG_VALUE_ACCESSOR
component to a reactive form using a custom directive with ComponentFactoryResolver
and ViewContainerRef
. The problem is that we can't assign a formControlName to the dynamically added component and we can't get the accessor value from the component.
我们尝试了几种不同的选项,但没有一个对我们有用(直接将formControlName添加到ngContainer会引发错误,还有ngComponentOutlet的一个选项,但我们无法为组件提供参数).
We tried several different options but none of them worked for us (directly adding formControlName to the ngContainer throws an error, also an option with ngComponentOutlet but we can't provide parameters to the component).
我们在plunker中创建了一个静态测试用例(我们想要达到的结果),并在指令中创建了一个动态测试用例,在该指令中我们无法为组件分配formControlName.我们将在下面的评论中提供链接.
We created a static test case in plunker (the result we want to reach) and a dynamic one which is using the directive where we can't assign formControlName to the component. We'll provide the links in the comment below.
推荐答案
您可以尝试扩展NgControl
.这是简单的实现.但这可能更复杂.
You can try to extend NgControl
. Here is simple implementation. But it might be more complex.
dynamic-panel.directive.ts
@Directive({
selector: '[dynamic-panel]'
})
export class DynamicPanelDirective extends NgControl implements OnInit {
name: string;
component: ComponentRef<any>;
@Output('ngModelChange') update = new EventEmitter();
_control: FormControl;
constructor(
@Optional() @Host() @SkipSelf() private parent: ControlContainer,
private resolver: ComponentFactoryResolver,
private container: ViewContainerRef) {
super();
}
ngOnInit() {
let component = this.resolver.resolveComponentFactory<GeneralPanelComponent>(GeneralPanelComponent);
this.name = 'general';
this.component = this.container.createComponent(component);
this.valueAccessor = this.component.instance;
this._control = this.formDirective.addControl(this);
}
get path(): string[] {
return [...this.parent.path !, this.name];
}
get formDirective(): any { return this.parent ? this.parent.formDirective : null; }
get control(): FormControl { return this._control; }
get validator(): ValidatorFn|null { return null; }
get asyncValidator(): AsyncValidatorFn { return null; }
viewToModelUpdate(newValue: any): void {
this.update.emit(newValue);
}
ngOnDestroy(): void {
if (this.formDirective) {
this.formDirective.removeControl(this);
}
if(this.component) {
this.component.destroy();
}
}
}
Modified Plunker
所以
如何将NG_VALUE_ACCESSOR组件动态添加到反应形式?
How to dynamically add NG_VALUE_ACCESSOR component to reactive form?
this.valueAccessor = this.component.instance;
就我而言
如果您想使用验证器,请参阅此 柱塞
If you want to use validators then see this Plunker
这篇关于如何动态地将NG_VALUE_ACCESSOR组件添加到反应形式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!