webentwicklung-frage-antwort-db.com.de

Auswahlelement an Objekt in Angular binden

Ich bin neu in Angular und versuche, mich mit der neuen Arbeitsweise vertraut zu machen.

Ich möchte ein ausgewähltes Element an eine Liste von Objekten binden - was ganz einfach ist:

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

In diesem Fall ist selectedValue anscheinend eine Zahl - die ID des ausgewählten Elements.

Eigentlich möchte ich mich jedoch an das Country-Objekt binden, sodass selectedValue das Objekt und nicht nur die ID ist. Ich habe versucht, den Wert der Option wie folgt zu ändern:

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

aber das scheint nicht zu funktionieren. Es scheint, ein Objekt in meinem selectedValue zu platzieren - aber nicht das Objekt, das ich erwarte. Sie können siehe dies in meinem Plunker-Beispiel .

Ich habe auch versucht, mich an das Änderungsereignis zu binden, damit ich das Objekt selbst basierend auf der ausgewählten ID festlegen kann. Es scheint jedoch, dass das Änderungsereignis ausgelöst wird, bevor das gebundene ngModel aktualisiert wird. Dies bedeutet, dass ich zu diesem Zeitpunkt keinen Zugriff auf den neu ausgewählten Wert habe.

Gibt es eine saubere Möglichkeit, ein ausgewähltes Element mit Angular 2 an ein Objekt zu binden?

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

StackBlitz-Beispiel

HINWEIS: Sie können [ngValue]="c" anstelle von [ngValue]="c.id" verwenden, wobei c das vollständige Länderobjekt ist.

[value]="..." unterstützt nur Zeichenfolgenwerte
[ngValue]="..." unterstützt jeden Typ

update

Wenn es sich bei value um ein Objekt handelt, muss die vorausgewählte Instanz mit einem der Werte identisch sein.

Siehe auch den kürzlich hinzugefügten benutzerdefinierten Vergleich https://github.com/angular/angular/issues/13268 verfügbar seit 4.0.0-beta.7

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

Achten Sie darauf, ob Sie innerhalb von this auf compareFn zugreifen möchten.

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

Dies könnte helfen:

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

Sie können dies auch tun, ohne [(ngModel)] in Ihrem <select> -Tag verwenden zu müssen

Deklarieren Sie eine Variable in Ihrer ts-Datei

toStr = JSON.stringify;

und in Ihrer Vorlage tun Sie dies

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

und dann verwenden

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

um die Zeichenfolge wieder in ein gültiges JavaScript-Objekt zu analysieren

16
Rahul Kumar

Es hat bei mir funktioniert:

Template HTML:

Ich habe (ngModelChange)="selectChange($event)" zu meinem select hinzugefügt.

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

Auf component.ts:

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

Und Sie müssen component.ts diese Funktion hinzufügen:

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

Hinweis: Ich versuche es mit [select]="oneOption.id==model.myListOptions.id" und arbeite nicht.

============== Eine andere Möglichkeit ist: =========

Template HTML:

Ich habe [compareWith]="compareByOptionId zu meinem select hinzugefügt.

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

Auf component.ts:

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

Und Sie müssen component.ts diese Funktion hinzufügen:

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

Nur für den Fall, dass jemand das Gleiche mit Reactive Forms tun möchte:

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

Überprüfen Sie das Arbeitsbeispiel hier

7
elvin

Sie können die ID mit einer Funktion auswählen

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

Für mich funktioniert es so, dass Sie event.target.value trösten können.

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

Wenn nichts anderes aus den angegebenen Lösungen funktioniert, überprüfen Sie, ob Sie "FormsModule" in "AppModule" importiert haben. Dies war ein Schlüssel für mich.

2

Erstellen Sie einen weiteren Getter für das ausgewählte Element

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

In ts:

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

Sie können den ausgewählten Wert auch mithilfe von click () abrufen, indem Sie den ausgewählten Wert durch die Funktion führen

<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