2016-06-25 35 views
1

如何将模板驱动控件添加到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; 
} 

如何添加从“子窗体”到“形式”,在“父窗体”,“酒吧”的控制?

更新:我找到类似的feature request

回答

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

如果你有“例外:后表达发生了变化它被检查。以前的值:'false'。当前值:'true'“,更改代码:

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

作为对Alexey的答案的一个说明,您应该添加OnDestroy处理程序以从表单控件中分离输入。如果你使用带有* ngIf的输入,这是特别需要的。

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