如何动态地将NG_VALUE_ACCESSOR组件添加到反应形式? [英] How to dynamically add NG_VALUE_ACCESSOR component to reactive form?

查看:151
本文介绍了如何动态地将NG_VALUE_ACCESSOR组件添加到反应形式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们想使用带有ComponentFactoryResolverViewContainerRef的自定义指令将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆