2016-06-25 34 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); 
 
    } 
 
}