2016-11-18 5 views
0

2つのコンポーネントにネストされたリアクティブフォームを作成しようとしています。 ParentComponentは問題なく動作しますが、私はChildComponentで問題を抱えています。このChildComponentはControlValueAccessorを使用しています。ネストされたリアクティブフォームの問題を構築する

質問:フィールドはビューに表示されますが、変更は親には行かないでください。どうして?私のControlValueAccessor機能は正しいですか?

child.component.html

<ul [formGroup]="fieldsForm"> 
    <li *ngFor="let field of fields"> 
     <label> 
     <input type="checkbox" [formControlName]="field.$key"> 
     {{field.$key}} 
     </label> 
    </li> 

</ul> 

child.component.ts

import {Component, OnInit, Input, ChangeDetectionStrategy} from '@angular/core'; 
import {FormGroup, FormBuilder, NG_VALUE_ACCESSOR, ControlValueAccessor} from "@angular/forms"; 
import {NodeService} from "../../node.service"; 

@Component({ 
    selector: 'child', 
    templateUrl: './child.component.html', 
    styleUrls: ['./child.component.scss'], 
    changeDetection: ChangeDetectionStrategy.OnPush, 
    providers: [ 
    {provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() =>ChildComponent), multi: true} 
    ] 
}) 
export class ChildComponent implements OnInit,ControlValueAccessor { 

    public fieldsForm: FormGroup; 
    public fields: any = []; 

    @Input() currentFilter; 
    @Input() formControlName; 

    constructor(private fb: FormBuilder, private nodeService: NodeService) { 
    this.fieldsForm = this.fb.group({}); 
    } 

    ngOnInit() { 
    this.getFilterValues(this.formControlName) 
    .subscribe(fields => { 
     const acc = {}; 
     this.fields = fields; 
     fields.forEach(field => acc[field.$key] = [true]); 
     this.fieldsForm = this.fb.group(acc); 
    }) 
) 

    registerOnChange(fn: (value: any) => void) { 
    this.fieldsForm.valueChanges.subscribe(fn); 
    } 

    registerOnTouched() {} 

    getFilterValues(type) { 
    return this.nodeService.getFilterValues(type, { 
     query: { orderByValue: true, equalTo: 1 } 
    }) 
    } 

} 

parent.component.ts

私は最後の3週間は、このフォームにしてきた3210
import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; 
import {FormBuilder, FormGroup} from "@angular/forms"; 
import {Input} from "@angular/core/src/metadata/directives"; 
import {Subject} from "rxjs"; 

@Component({ 
    selector: 'filter', 
    templateUrl: './filter.component.html', 
    styleUrls: ['./filter.component.scss'], 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class ParentComponent implements OnInit { 

    public form: FormGroup; 
    public groupsForm:Subject<any> = new Subject(); 

    @Input() groups; 
    @Input() currentFilters; 

    constructor(private fb: FormBuilder) { 
    this.form = this.fb.group({}) 
    } 

    ngOnChanges() { 
    const acc = {}; 
    this.groups.map(group => { 
     acc[group] = []; 
    }); 
    this.groupsForm.next(acc); 
    } 

    ngOnInit() { 
    this.groupsForm.subscribe(groupForm => this.form =  this.fb.group(groupForm)); 

    // Detect changes from from 
    this.form.valueChanges 
    .subscribe(console.log) 
    } 

} 

parent.component.html

<form [formGroup]="form" novalidate> 
    <fieldset *ngFor="let group of groups"> 

    <child [formControlName]="group" [currentFilter]="currentFilters[group]"></child> 

    </fieldset> 
</form> 

。私は両方のタイプのフォーム、ネストされたコンポーネント、または単一のコンポーネントでそれを行いました。私はControlValueAccessorを使用するように感じる。私は誰かが私を助けることを願っています。ありがとう!

+0

'console.log()'は、あなたのコードには何もありません。 – n00dl3

+0

私はそれを追加しました。それは 'this.filtersValues $'のサブスクリプションにあります – Tom

答えて

0

プロバイダーをより高いレベルで登録するべきではありませんか?例えば。 ParentComponentに?今すぐNG_VALUE_ACCESSORChildComponentとその子供のために利用可能です。

子どもに@Inputとして渡すだけで、ネストされたコンポーネントと反応性フォームを混合する方法が異なります。 Works for me

関連する問題