web-dev-qa-db-ja.com

Angular4フォーム-追加のフィールドでモデル化するformGroupsetValue

angular 4の既存のモデルクラスのフィールドの一部だけを更新するフォームがあります。

現在のモデルインスタンスでsetValueを実行し、最後に値を更新し直す必要があります。

問題は、モデルの一部のみを更新する必要があるのですが、angularフォームはエラーを返します

"Cannot find form control with name 'fieldname'" 

編集したくない余分なフィールドのために。

必要な動作を取得するための最善のオプションは何ですか?

フォームで更新したくないフィールドに非表示のformControlsを追加することを考えましたが、一部のモデルはかなり大きく、ユーザーはそれらの一部のみを編集する必要があります。

モデルのダーティチェックと一般的な更新のために、最後に更新されたモデルを取得する必要があります(すべてのformControlsの値を設定し、送信時にformControlsからモデルを更新するためだけに複数の重複するクラス関連コードがある場合と比較して)

ありがとう。

明確にするためだけに更新-これに似た動作が必要です:

--component.ts
model: Model = someModelWithData;

--component.html
<input type="checkbox" [(NgModel)]="model.FieldOne" />

ユーザーがFieldOneの値を変更した後も、モデルは他のすべてのデータでいっぱいですが、FieldOneは変更されています。

7
Royi Mindel

patchValueの代わりにメソッドsetValueを使用してフォームの一部を更新できます。

this.yourForm.patchValue({
     yourFieldToUpdate: yourValue
});
10
HMarteau

Angularは、フォームモデルとデータモデルを分離するように構築されています。

ドキュメントから:

リアクティブパラダイムに沿って、コンポーネントはデータモデルの不変性を保持し、元の値の純粋なソースとして扱います。コンポーネントは、データモデルを直接更新するのではなく、ユーザーの変更を抽出して外部コンポーネントまたはサービスに転送します。外部コンポーネントまたはサービスは、データモデルを処理して(保存など)、更新されたモデルの状態を反映する新しいデータモデルをコンポーネントに返します。

ただし、フォーム内のデータモデルにバインドする場合は、 ngModelOptionsスタンドアロンをtrue に設定できます。

スタンドアロン:デフォルトはfalseです。これがtrueに設定されている場合、ngModelはそれ自体を親フォームに登録せず、フォームにないかのように動作します。これは、フォームの表示を制御するが、フォームデータを含まない、タグにネストされたフォーム要素であるフォームメタコントロールがある場合に便利です。

スタックブリッツの例

この例では、モデルに3つのフィールドがあり、そのうち2つはフォームで編集できます。

model.ts

export class Model {
  fieldOne: string;
  fieldTwo: string;
  fieldThree: string;

  constructor(fieldOne: string, fieldTwo: string, fieldThree: string)
  {
    this.fieldOne = fieldOne;
    this.fieldTwo = fieldTwo;
    this.fieldThree = fieldThree;
  }
}

app.component.ts

import {Component, OnInit} from '@angular/core';
import {AbstractControl, FormBuilder, FormGroup} from '@angular/forms';

import {Model} from './model';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  private _form
  private _model: Model;

  get form(): FormGroup {
    return this._form;
  }

  get model(): Model {
    return this._model;
  }

  set model(model: Model) {
    this._model = model;
  }

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit() {
    this.model = this.newModel();
    this.createForm();
  }

  private newModel(): Model {
    return new Model('fieldOne', 'fieldTwo', 'fieldThree');
  }

  private createForm() {
    this._form = this.formBuilder.group({
    });
  }
}

app.component.html

フォームの値が変更されると、実際のデータモデルが更新され、編集可能なフィールドのみがフォームを介して変更できるようになります。

<form [formGroup]="form">
  <div>
    <label for="fieldOne">Field One</label>
    <input
      id="fieldOne"
      type="text"
      [(ngModel)]="model.fieldOne"
      [ngModelOptions]="{ standalone: true }">
  </div>

  <div>
    <label for="fieldTwo">Field Two</label>
    <input
      id="fieldTwo"
      type="text"
      [(ngModel)]="model.fieldTwo"
      [ngModelOptions]="{ standalone: true }">
  </div>
</form>

<h3>Model</h3>
<pre>{{ model | json }}</pre>
5
josavish

(モデル内の)フィールドを更新するコントロールのみに2つの方法をバインドし、angular double curlyexpressionsを使用して値を残りに設定する)はどうですか?

例えば。

<input type="checkbox" [(NgModel)]="model.FieldOne">
<input type="text" name="fieldone" [(NgModel)]="model.FieldOne">
<input type="text" name="fieldtwo"[(NgModel)]="model.FieldTwo">
<input type="text" name="ignore1" value ="{{model.Ignore1}}">
<input type="hidden" name="ignore2" value ="{{model.Ignore2}}">
2
steve biko