狛ログ

2018年11月15日木曜日

AngularのFormでのselect要素の使い方(selected指定の方法)


オフィス狛 技術部のKoma(Twitterアカウントの中の人&CEO)です。

何だか分かり難い題名ですいません。良い題名が思いつきませんでした。

さて、やりたい事から説明しようと思います。

Angularで、Formに入力した値をPOSTする時、ちょっとやり方迷うのがselect要素です。
プルダウンってやつですね。

こんな感じのFormは良くあるかと思います。
初期表示時に先頭を選択状態にしておくのは簡単ですが、
データの修正を行う機能などは、「APIで取得した値を選択状態に」って事は良くあります。

例えば、このようなJSONがAPIから返却されるとします。
{"list": [
        {"api-data-status": 1},
        {"api-data-status": 2},
        {"api-data-status": 3}
 ]}

まずはプルダウンに表示する値(value)と名称(name)を定義します。
【constants.ts】
export namespace testDataStatus {
  export const STATUS_1 = { value: 1, name: 'ステータス1' };
  export const STATUS_2 = { value: 2, name: 'ステータス2' };
  export const STATUS_3 = { value: 3, name: 'ステータス3' };
}

続いて、コンポーネント側でプルダウン用のリスト定義します。
先程の定義した定数を使用しています。
【test-data-status.component.ts】
  testDataStatusOption: Array<{ status: number; name: string }> = [
    {
      status: Constants.testDataStatus.STATUS_1.value,
      name: Constants.testDataStatus.STATUS_1.name
    },
    {
      status: Constants.testDataStatus.STATUS_2.value,
      name: Constants.testDataStatus.STATUS_2.name
    },
    {
      status: Constants.testDataStatus.STATUS_3.value,
      name: Constants.testDataStatus.STATUS_3.name
    }
  ];

そして、最後はView(html)側ですが・・・下記のように記載すると、うまく行きません
【test-data-status.component.html】(NGな例)
<ng-container *ngFor="let item of statusList.list">
    <select class="form-control" formControlName="testDataStatus">
        <option *ngFor="let hoge of testDataStatusOption"
              [ngValue]="hoge.status"
              [selected]="hoge.status === item.api-data-status">
              {{report.name}}
        </option>
    </select>
</ng-container>
「statusList.list」がAPIで取得したデータです。
それを最初の「ngFor」で繰り返してデータ数分のプルダウンを作り、二番目の「ngFor」からプルダウンの値(value)と名称(name)を作り、APIの値と比較して「selected」に値を設定する・・・一見うまく行きそうなんですけどね。これではダメです。

という訳で、うまく行く書き方は以下の通りです。
【test-data-status.component.html】(OKな例)
<ng-container *ngFor="let item of statusList.list">
  <select class="form-control form-control-sm" [(ngModel)]="item.api-data-status" formControlName="testDataStatus">
    <option *ngFor="let hoge of testDataStatusOption"
        [ngValue]="hoge.status">
        {{hoge.name}}
    </option>
  </select>
</ng-container>
まあ、良く考えると当たり前なのですが、
「[(ngModel)]」に値を設定する事で、APIから取得した値で選択状態とする事が出来ます。

view(html)表示だけだと、そこまで難しくないのですが、FormControlを使うと少しややこしくなるので、自分の備忘録の為に記事にしました。

それでは、良いAngularライフを!


0 件のコメント:

コメントを投稿