web-dev-qa-db-ja.com

select要素をAngular内のオブジェクトにバインドします

私はAngularが初めてで、新しいやり方でスピードを速めようとしています。

Select要素をオブジェクトのリストにバインドしたいのですが、これで十分簡単です。

@Component({
   selector: 'myApp',
   template: `<h1>My Application</h1>
              <select [(ngModel)]="selectedValue">
                 <option *ngFor="#c of countries" value="c.id">{{c.name}}</option>
              </select>`
})
export class AppComponent{
    countries = [
       {id: 1, name: "United States"},
       {id: 2, name: "Australia"}
       {id: 3, name: "Canada"},
       {id: 4, name: "Brazil"},
       {id: 5, name: "England"}
     ];
    selectedValue = null;
}

この場合、selectedValueは数値、つまり選択されたアイテムのIDになります。

しかし、selectedValueが単なるidではなくオブジェクトになるように、実際にはcountryオブジェクト自体にバインドしたいと思います。このようにオプションの値を変更してみました。

<option *ngFor="#c of countries" value="c">{{c.name}}</option>

しかしこれはうまくいかないようです。それは私のselectedValueにオブジェクトを置くようです - しかし私が期待しているオブジェクトではありません。あなたは 私のPlunkerの例でこれを見ることができます

また、選択したIDに基づいてオブジェクトを自分で設定できるように、changeイベントにバインドしてみました。しかし、バインドされたngModelが更新される前にchangeイベントが発生するようです。つまり、その時点では新しく選択された値にアクセスできません。

Angular 2を使用してselect要素をオブジェクトにバインドするきれいな方法はありますか?

320
RHarris
<h1>My Application</h1>
<select [(ngModel)]="selectedValue">
  <option *ngFor="let c of countries" [ngValue]="c">{{c.name}}</option>
</select>

StackBlitzの例

注:[ngValue]="c"の代わりに[ngValue]="c.id"を使用できます。ここで、cは完全な国別オブジェクトです。

[value]="..."は文字列値のみをサポートします
[ngValue]="..."は任意の型をサポートします

更新

valueがオブジェクトの場合、事前に選択されたインスタンスはいずれかの値と同一である必要があります。

最近追加されたカスタム比較 もご覧ください。https://github.com/angular/angular/issues/132684.0以降0.0ベータ7

<select [compareWith]="compareFn" ...

this内でcompareFnにアクセスしたい場合は注意してください。

compareFn = this._compareFn.bind(this);

// or 
// compareFn = (a, b) => this._compareFn(a, b);

_compareFn(a, b) {
   // Handle compare logic (eg check if unique ids are the same)
   return a.id === b.id;
}
601

これは役に立ちます。

<select [(ngModel)]="selectedValue">
      <option *ngFor="#c of countries" [value]="c.id">{{c.name}}</option>
</select>
35
Carolina Faedo

<select>タグで[(ngModel)]を使う必要なしにこれをすることもできます

Tsファイルで変数を宣言する

toStr = JSON.stringify;

そしてあなたのテンプレートでこれを行います

 <option *ngFor="let v of values;" [value]="toStr(v)">
      {{v}}
 </option>

そして使用する

let value=JSON.parse(event.target.value)

文字列を解析して有効なJavaScriptオブジェクトに戻す

16
Rahul Kumar

それは私のために働きました:

テンプレートHTML:

select(ngModelChange)="selectChange($event)"を追加しました。

<div>
  <label for="myListOptions">My List Options</label>
  <select (ngModelChange)="selectChange($event)" [(ngModel)]=model.myListOptions.id >
    <option *ngFor="let oneOption of listOptions" [ngValue]="oneOption.id">{{oneOption.name}}</option>
  </select>
</div>

component.tsの場合:

  listOptions = [
    { id: 0, name: "Perfect" },
    { id: 1, name: "Low" },
    { id: 2, name: "Minor" },
    { id: 3, name: "High" },
  ];

この関数にcomponent.tsを追加する必要があります。

  selectChange( $event) {
    //In my case $event come with a id value
    this.model.myListOptions = this.listOptions[$event];
  }

注意:私は[select]="oneOption.id==model.myListOptions.id"を試してみましたが動作しません。

=============別の方法があります:=========

テンプレートHTML:

select[compareWith]="compareByOptionIdを追加しました。

<div>
  <label for="myListOptions">My List Options</label>
  <select [(ngModel)]=model.myListOptions [compareWith]="compareByOptionId">
    <option *ngFor="let oneOption of listOptions" [ngValue]="oneOption">{{oneOption.name}}</option>
  </select>
</div>

component.tsの場合:

  listOptions = [
    { id: 0, name: "Perfect" },
    { id: 1, name: "Low" },
    { id: 2, name: "Minor" },
    { id: 3, name: "High" },
  ];

この関数にcomponent.tsを追加する必要があります。

 /* Return true or false if it is the selected */
 compareByOptionId(idFist, idSecond) {
    return idFist && idSecond && idFist.id == idSecond.id;
 }

関数を使ってIDを選択できます

<option *ngFor="#c of countries" (change)="onchange(c.id)">{{c.name}}</option>
5
Eng.Gabr

このように動作している私にとっては、event.target.valueをコンソールにすることができます。

<select (change) = "ChangeValue($event)" (ngModel)="opt">   
    <option *ngFor=" let opt of titleArr" [value]="opt"></option>
</select>
4
Shubhranshu

万が一誰かがReactive Formsを使って同じことをしようとしているのなら:

<form [formGroup]="form">
  <select formControlName="country">
    <option *ngFor="let country of countries" [ngValue]="country">{{country.name}}</option>
  </select>
  <p>Selected Country: {{country?.name}}</p>
</form>

ここで動作例 を確認してください

3
elvin

また、与えられたソリューションの他に何もうまくいかない場合は、 "AppModule"の中に "FormsModule"をインポートしたかどうかを確認してください。これが私にとっての鍵でした。

2

選択したアイテムに別のゲッターを作成

<form [formGroup]="countryForm">
  <select formControlName="country">
    <option *ngFor="let c of countries" [value]="c.id">{{c.name}}</option>
  </select>

  <p>Selected Country: {{selectedCountry?.name}}</p>
</form>

Tsで:

get selectedCountry(){
  let countryId = this.countryForm.controls.country.value;
  let selected = this.countries.find(c=> c.id == countryId);
  return selected;
}
1
Rafi

関数に選択された値を渡すことでclick()の助けを借りても選択された値を得ることができます

<md-select placeholder="Select Categorie"  
    name="Select Categorie" >
  <md-option *ngFor="let list of categ" [value]="list.value" (click)="sub_cat(list.category_id)" >
    {{ list.category }}
  </md-option>
</md-select>
1
Jose Kj