带有组件的模板驱动表单

时间:2016-06-25 21:08:34

标签: angular

如何将模板驱动的控件添加到ngForm?

例如,我有两个组件的表单:

@Component({
    selector: 'parent-form',
    template: '<form #form="ngForm">
      <input required [(ngModel)]="model.foo" name="foo">
      <child-form [model]="model"></child-form>
    </form>',
    directives: [ REACTIVE_FORM_DIRECTIVES, ChildFormComponent ]
})
export class ParentFormComponent {
    public model: MyModel = new MyModel();
}

@Component({
    selector: 'child-form',
    template: '<fieldset>
      <input required [(ngModel)]="model.bar" name="bar">
    </fieldset>',
    directives: [ REACTIVE_FORM_DIRECTIVES ]
})
export class ChildFormComponent {
    @Input() public model: MyModel;
}

如何将“bar”控件从“子窗体”添加到“父窗体”中的“窗体”?

更新:我发现了类似的feature request

2 个答案:

答案 0 :(得分:4)

作为修补程序,您可以使用“RegisterFormModelDirective”:

import { Directive, ElementRef, Input, OnInit } from '@angular/core';
import { NgModel, NgForm } from '@angular/forms';

@Directive({
    selector: '[registerForm]'
})
export class RegisterFormModelDirective implements OnInit {
    private el: HTMLInputElement;

    @Input('registerForm') public form: NgForm;
    @Input('registerModel') public model: NgModel;

    constructor(el: ElementRef) {
        this.el = el.nativeElement;
    }

    ngOnInit() {
        if (this.form && this.model) {
            this.form.form.addControl(this.model.name, this.model.control);
        }
    }
}

这条指令:

<input [(ngModel)]="myValue" minlength="10" #myInput="ngModel" #myComp
  name="childValue" [registerForm]="form" [registerModel]="myInput">

请参阅plunkr演示:https://plnkr.co/edit/GG2TVHHHGbAzoOP5mIRr?p=preview

如果您有“EXCEPTION:表达式在检查后已更改。上一个值:'false'。当前值:'true'”,更改代码:

public ngOnInit() {
    if (this.form && this.model) {
        this.form.form.registerControl(this.model.name, this.model.control);
        this.form.addControl(this.model);
    }
}

答案 1 :(得分:0)

作为对Alexey的回答的旁注,您应该添加OnDestroy处理程序以从表单控件中取消输入。如果您使用* ngIf输入,则尤其需要这样做。

&#13;
&#13;
public ngOnDestroy() {
    if (this.form && this.model) {
        this.form.removeControl(this.model);
    }
}
&#13;
&#13;
&#13;