2017-09-20 3 views
3

私は2つのコンポーネントがあります。parentComponentにとChildComponent:フォームのフォーム。フォームコントロールの継承ができますか?

parent.component.ts

<form #form="ngForm" (ngSubmit)="onSubmit(form)" novalidate> 
    <input type="text" name="firstControl" [(ngModel)]="firstControl" /> 
    <input type="text" name="secondControl" [(ngModel)]="secondControl" /> 
    <child-component> 
</form> 
{{form.value | json}} 

child.component.ts今

<input type="text" name="thirdControl" [(ngModel)]="thirdControl" /> 
<input type="text" name="fourthControl" [(ngModel)]="fourthControl" /> 

{{form.value | json}}戻り{ "firstControl": "", "secondControl": "" }、それはだが明らかです。私の質問は:子コンポーネントからフォームコントロールを継承する方法はありますか? ParentComponentの{ "firstControl": "", "secondControl": "", "thirdControl": "", "fourthControl": "" }を取得する正しい方法は何ですか?出来ますか?

答えて

4

更新:

import { FormsModule, ControlContainer, NgForm, NgModel } from '@angular/forms'; 

@Component({ 
    ... 
    viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ] 
}) 
export class ChildComponent {} 

も前のバージョンを参照してください:

は確かに簡単な方法があります:

私はそれが可能だと言います。たとえば、あなたは

import { NgForm, NgModel } from '@angular/forms'; 

@Component({ 
    selector: 'child-component', 
    template: ` 
     <input type="text" name="thirdControl" [(ngModel)]="thirdControl" /> 
     <input type="text" name="fourthControl" [(ngModel)]="fourthControl" /> 
    ` 
}) 
export class ChildComponent { 
    @ViewChildren(NgModel) ngModels: QueryList<NgModel>; 

    constructor(@Optional() private ngForm: NgForm) {} 

    ngAfterViewInit() { 
    if (this.ngForm) { 
     this.ngModels.forEach(model => this.ngForm.addControl(model)); 
    } 
    } 
} 

Plunker Example

角度DIシステムは私たちに、親NgFormインスタンスへの参照を取得する機会を与えるあなたの

child.component.tsに次のコードを追加することができますので、角度依存性解決アルゴリズムは、現在のノードから始まり、要素ツリーを経て上がる。私たちは、フォーム要素では、次の順序

child-component 
    || 
    \/ 
    form 
    || 
    \/ 
    my-app 
    || 
    \/ 
    @NgModule 

でそれを検索しますNgFormトークン角度要求していたときに私の例では、NgFormディレクティブはそれを得ることができるときに置かれfollwingツリーだから、

   @NgModule providers 
        | 
        my-app 
        | 
        form 
     /  |  \ 
    input[text] input[text] child-component 

を想像することができます。またproviders配列内のNgFormディレクティブで宣言されたトークンを得ることができます。このルールはどのノードにも適用されます。

ので、彼らが一緒に動作するはずも手動NgFormからAngular 2 - How does ng-bootstrap provide the NgbRadioGroup and NgbButtonLabel to their NgbRadio directive?

その後、私はちょうど追加された子NgModelディレクティブを参照してください。

+2

どのような素晴らしい投稿です! – Vega

+0

完璧な説明。ありがとう、おいおい。 –

0

Angularには、Template DrivenとReactiveという2種類のフォームがあります。テンプレートドリブンフォームではできないことを調べる必要があります。Reactive Forms

一般に、コンポーネントでフォームオブジェクトを作成し、それをテンプレートで使用することで機能します。 Angularはこれが実際にはもっと柔軟でテストするのが簡単だと言っていますが、私は構文があなたの頭を包むのがずっと難しいと思います。

あなたの親コンポーネントでこれをお勧めします:

myForm: FormGroup; 

    constructor(private fb: FormBuilder) { // <--- inject FormBuilder 
    this.createForm(); 
    } 

    createForm() { 
    this.myForm = this.fb.group({ 
     firstControl: '', 
     secondControl: '', 
     thirdControl: '', 
     fourthControl: '' 
    }); 
    } 

あなたの親テンプレートは、次のようになります。

<form [formGroup]="myForm" novalidate> 
<input type="text"formControlName="firstControl" /> 
    <input type="text" formControlName="secondControl" /> 
    <child-component [parentFormGroup]="myForm"> 
</form> 

入力としてフォーム・グループを受け入れるあなたの子供、そしてテンプレートは次のようになります。

<div class="form-group" [formGroup]="parentFormGroup"> 
    <input type="text" formControlName="thirdControl" /> 
    <input type="text" formControlName="fourthControl" /> 
</div> 
関連する問題