2017-08-30 11 views
1

フォームグループには、いくつかのフォームコントロール値が他のフォームコントロール値に依存するフォームグループがあります。私の特定のケースでは、それらは相互に依存していますが、これは簡単のために以下の例には示されていません。FormGroup内の従属フォームコントロールの初期設定

ここにはplunkがあります。

const fetchedFormValues = { 
    timestamp: '1504116487374' 
}; 

Observable.from(this.form.get('timestamp').valueChanges) 
.filter(v => v) 
.distinctUntilChanged() 
.subscribe(timestamp => { 
    console.log('timestamp', timestamp); 
    this.form.get('date').setValue(new Date(timestamp).toISOString().substr(0, 10)); 
    this.form.get('time').setValue(new Date(timestamp).toISOString().substr(11, 12)) 
}); 

this.form.reset(fetchedFormValues); 

初期フォームの値は、バックエンドからフェッチされ(これは、後に行うことができる)resetで設定されています。問題は、datetimesetValueは、timestampが変更されたときに正常に機能しますが、リセット時は無視されます。

私はそれをできるだけ乾燥した状態に保ち、複数の場所でthis.form.get('date').setValue...を避けるようにしています。これは既にリストされている観測で行われているためです。

なぜdatetimeフォームコントロールはtimestampのサブスクリプションの影響を受けませんresetsetValueで行われた変更を受け入れるようにresetの動作を修正できますか?依存型コントロールを(相互に)扱う他の方法はありますか?

FormGroup.prototype.reset = function (value, options) { 
    if (value === void 0) { value = {}; } 
    if (options === void 0) { options = {}; } 
    this._forEachChild(function (control, name) { 
     control.reset(value[name], { onlySelf: true, emitEvent: options.emitEvent }); 
    }); 
    this.updateValueAndValidity(options); 
    this._updatePristine(options); 
    this._updateTouched(options); 
}; 

あなたのケースでthis._forEachChildために、コントロールを返します:

答えて

1

FormGroupのreset()機能は次のようになります

  1. タイムスタンプ
  2. 時間

タイムスタンプフィールドが設定されている場合、そのvalueChangesがトリガされ、他の2つのフィールドが正しく設定されますが、これらの2つのフィールドは(value[name])に再度this._forEachChild回反復されます。

ので、最速の修正はにあなたのフィールドの順序を変更するには、次のようになります。

this.form = this.fb.group({ 
    date: null, 
    time: null, 
    timestamp: null 
}); 

このようdatetimeフィールドはundefinedに設定され、その後、最後の反復で「タイムスタンプ」フィールドが入力されますdatetimeフィールドの値を変更します。

resetの代わりに、patchValue関数を使用するのがもう1つ(私にとっては好ましい)ソリューションです。それが関数に表示されたフィールド上でのみ反復処理ではなく、コントロールの上に

FormGroup.prototype.patchValue = function (value, options) { 
    var _this = this; 
    if (options === void 0) { options = {}; } 
    Object.keys(value).forEach(function (name) { 
     if (_this.controls[name]) { 
      _this.controls[name].patchValue(value[name], { onlySelf: true, emitEvent: options.emitEvent }); 
     } 
    }); 
    this.updateValueAndValidity(options); 
}; 

:ようpatchValue機能が見えます。したがって、あなたのケースでは、timestampフィールドのみが更新され、valueChangesイベントエミッタをトリガします。

ので、代わりのpatchValue

this.form.reset(fetchedFormValues); 

書き込み

this.form.patchValue(fetchedFormValues); 

あなたもvalueChangesエミッタのトリガを制御することができます。あなたは(あなたのケースではありません)valueChangesがトリガさせたくない場合は、書くことができます。

this.form.patchValue(fetchedFormValues, {emitEvent: false}); 

参照コードソース:https://unpkg.com/@angular/[email protected]/bundles/forms.umd.js

+0

おかげで、それを; sの偉大な説明を、効率的かつシンプルな。ここで秩序が重要であるとは決して考えられませんでした。オブジェクト小道具が順序付けられていないという事実を考慮して設計されているのだろうか?残念ながら、patchValueはresetと互換性がありません。これは私が試した最初のものでした(フォーム配列ではじめてです)。 – estus

関連する問題