web-dev-qa-db-fra.com

Lier un élément à l’objet dans Angular

Angular je suis nouveau et j'essaie de m'adapter à la nouvelle façon de faire les choses.

J'aimerais lier un élément select à une liste d'objets - ce qui est assez simple:

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

Dans ce cas, il apparaît que selectedValue serait un nombre - l'identifiant de l'élément sélectionné.

Cependant, je voudrais en fait me lier à l'objet pays lui-même pour que selectedValue soit l'objet plutôt que simplement l'ID. J'ai essayé de changer la valeur de l'option comme ceci:

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

mais cela ne semble pas fonctionner. Il semble placer un objet dans ma selectedValue - mais pas l'objet que j'attends. Vous pouvez voir ceci dans mon exemple Plunker .

J'ai également essayé de lier l'événement change afin de pouvoir définir l'objet moi-même en fonction de l'ID sélectionné; cependant, il semble que l'événement change se déclenche avant que le ngModel lié ne soit mis à jour, ce qui signifie que je n'ai pas accès à la nouvelle valeur sélectionnée à ce stade.

Existe-t-il un moyen simple de lier un élément de sélection à un objet avec Angular 2?

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

exemple StackBlitz

REMARQUE: vous pouvez utiliser [ngValue]="c" à la place de [ngValue]="c.id", où c est l’objet pays complet.

[value]="..." ne supporte que les valeurs de chaîne
[ngValue]="..." supporte tous les types

mettre à jour

Si value est un objet, l'instance présélectionnée doit être identique à l'une des valeurs.

Voir également la comparaison personnalisée récemment ajoutée https://github.com/angular/angular/issues/13268 disponible depuis la version 4.0.0-beta.7

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

Faites attention si vous voulez accéder à this dans 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;
}
626
Günter Zöchbauer

Cela pourrait aider:

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

Vous pouvez le faire aussi sans avoir besoin d'utiliser [(ngModel)] dans votre balise <select>

Déclarer une variable dans votre fichier ts

toStr = JSON.stringify;

et dans votre modèle le faire

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

et ensuite utiliser

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

analyser la chaîne dans un objet JavaScript valide

16
Rahul Kumar

Cela a fonctionné pour moi:

Template HTML:

J'ai ajouté (ngModelChange)="selectChange($event)" à mon 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>

Sur composant.ts:

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

Vous devez ajouter à component.ts cette fonction:

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

Note: J'essaie avec [select]="oneOption.id==model.myListOptions.id" et ne fonctionne pas.

============= Une autre manière peut être: =========

Template HTML:

J'ai ajouté [compareWith]="compareByOptionId à mon 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>

Sur composant.ts:

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

Vous devez ajouter à component.ts cette fonction:

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

Juste au cas où quelqu'un voudrait faire la même chose en utilisant des formulaires réactifs:

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

Vérifiez l'exemple de travail ici

7
elvin

Vous pouvez sélectionner l'ID à l'aide d'une fonction

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

Pour moi, ça marche comme ça, vous pouvez console event.target.value.

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

En outre, si rien d'autre dans les solutions données ne fonctionne, vérifiez si vous avez importé "FormsModule" dans "AppModule", ce qui était une clé pour moi.

2
nikola.maksimovic

Créer un autre getter pour l'élément sélectionné

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

En ts:

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

Vous pouvez également obtenir la valeur sélectionnée à l'aide de click () en transmettant la valeur sélectionnée via la fonction

<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