Ligar o elemento de selecção ao objecto em Angular

Sou novo no Angular e tento actualizar-me com a nova forma de fazer as coisas.

gostaria de ligar um elemento select a uma lista de objectos -- o que é fácil:

@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;
}

neste caso, parece que o valor seleccionado seria um número -- o id do item seleccionado.

No entanto, gostaria de ligar-me ao próprio objecto do país para que o valor selected seja o objecto e não apenas o id. Eu tentei mudar o valor da opção como então ...
<option *ngFor="#c of countries" value="c">{{c.name}}</option>
Mas isto não parece funcionar. Parece colocar um objeto no meu valor selecionado -- mas não o objeto que estou esperando. Podes ver isto no meu exemplo de mergulho.

também tentei ligar-me ao evento de mudança para poder definir o objecto com base no id seleccionado; contudo, parece que o evento de mudança dispara antes do ngModel ligado ser actualizado -- o que significa que não tenho acesso ao valor recentemente seleccionado nesse ponto.

Existe uma uma forma limpa de ligar um elemento select a um objecto com o Angular 2?

 267
Author: Lazar Ljubenović, 2016-03-11

9 answers

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

Exemplo de StackBlitz

Nota: pode utilizar [ngValue]="c" em vez de [ngValue]="c.id" onde c é o objecto completo do país.

[value]="..." só suporta valores de texto
[ngValue]="..." suporta qualquer tipo

Actualizar

Se o value é um objecto, a instância pré-seleccionada precisa de ser idêntica a um dos valores.

Ver também a comparação personalizada recentemente adicionada https://github.com/angular/angular/issues/13268 disponível desde 4, 0-beta.7

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

Tome cuidado se quiser aceder this dentro de compareFn.

compareFn = this._compareFn.bind(this);

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

_comareFn((a, b) {
   if(this.x ...) {
     ...
}
 493
Author: Günter Zöchbauer, 2018-03-19 07:27:35
Isto pode ajudar.

<select [(ngModel)]="selectedValue">
      <option *ngFor="#c of countries" [value]="c.id">{{c.name}}</option>
</select>
 29
Author: Carolina Faedo, 2016-12-15 14:41:36

Você pode fazer isso também sem a necessidade de usar [(ngModel)] na sua marca <select>

Declare uma variável no seu ficheiro ts

toStr = JSON.stringify;

E no seu modelo faça isto

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

E depois usar

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

Para processar o texto de volta para um objecto de JavaScript válido

 12
Author: Rahul Kumar, 2017-05-04 05:36:00

Pode seleccionar o Id usando uma função

<option *ngFor="#c of countries" (change)="onchange(c.id)">{{c.name}}</option>
 5
Author: Eng.Gabr, 2017-01-24 10:05:13
Funcionou comigo.

Modelo HTML:

Adicionei (ngModelChange)="selectChange($event)" ao meu select.

<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>

no componente.ts:

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

An você precisa adicionar a component.ts Esta função:

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

Nota: Eu tento com [select]="oneOption.id==model.myListOptions.id" e não trabalho.

============= outras maneiras podem ser: =========

Modelo HTML:

Adicionei [compareWith]="compareByOptionId à minha select.

<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>

no componente.ts:

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

An você precisa adicionar a component.ts Esta função:

 /* Return true or false if it is the selected */
 compareByOptionId(idFist, idSecond) {
    return idFist && idSecond && idFist.id == idSecond.id;
 }
 5
Author: Jose Carlos Ramos Carmenates, 2018-06-29 00:32:06
Para mim, é assim que funciona, podes consolar.
<select (change) = "ChangeValue($event)" (ngModel)="opt">   
    <option *ngFor=" let opt of titleArr" [value]="opt"></option>
</select>
 4
Author: Shubhranshu, 2017-12-24 07:54:28

Só no caso de alguém querer fazer o mesmo usando formas reactivas:

<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>

Veja o exemplo de trabalho aqui

 3
Author: elvin, 2018-04-05 20:56:03

Além disso, se nada mais de soluções dadas não funcionar, verifique se importou "FormsModule" dentro de "AppModule", que era uma chave para mim.

 2
Author: nikola.maksimovic, 2018-01-14 21:24:17

Você pode obter o valor seleccionado também com a ajuda do click (), passando o valor seleccionado através da função

<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
Author: Jose Kj, 2017-05-25 11:40:33