shrimpdrake
shrimpdrake

Reputation: 1576

Bind each array element to option tag

I am trying to bind an array element from a class to an option tag.

In the angular.io "Tour of Hero" tutorial ( https://angular.io/docs/ts/latest/tutorial/toh-pt2.html ) they do the following for a list :

  <li *ngFor="let hero of heroes"
    (click)="onSelect(hero)">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>

If I understand it right the *ngFor="let hero of heroes" will associate each hero ( so each element in the heroes array ) to a li element and then display some caracteristics of the associated hero with {{hero.id}} for example.

I say associate because if it was just a simple loop with a print I don't see how they would get back the hero object after with onSelect(hero).

I have been trying to do the same with option :

   <option *ngFor="let perso of persos">
     <span>{{perso.id}} : </span> {{perso.nom}}
   </option>

But

(click)="onSelect(hero)"

isn't effective since then click event isn't triggered with option. I couldn't find the right trigger. Any help and additionnal information is very welcomed.

Upvotes: 2

Views: 1447

Answers (2)

Maximilian Riegler
Maximilian Riegler

Reputation: 23506

For those native HTML elements Angular 2 offers two-way-bindings, so you can bind your values directly with ngModel - this works for all input tags. So if you change the selection manually, it also updates that variable with the current value. Also if you change selectedPerso programmatically, the view gets updated with the new selection.

<select [(ngModel)]="selectedPerso" (change)="onChange($event)">
    <option *ngFor="let perso of persos" [value]="perso.id">
        <span>{{perso.id}} : </span> {{perso.nom}}
    </option>
</select>

And in your component class body you define that binding variable with a default value which gets preselected on page load:

selectedPerso: number = persos[0].id;

onChange(event) {
    console.log("Selection changed: ", event);
}

Upvotes: 3

Alexandre Junges
Alexandre Junges

Reputation: 988

You can't bind a object to the [value] property of the option element.

I would bind the object's id to the [value] property of the option element and use the (change) event of the select.

See the example below:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    Select your favorite serie:

    <select (change)="onChange($event.target.value)">
      <option *ngFor="let serie of series" [value]="serie.id">{{ serie.name }}</option>
    </select>

    <br />
    <br />

    Selected Serie: <br />
    <span *ngIf="selectedSerie">
      {{ selectedSerie.id  }} - {{ selectedSerie.name }}
    </span>
  `
})
export class AppComponent {

  private series: any[];
  private selectedSerie: any;

  constructor() {
    this.series = [
      { id: 1, name: 'Friends' },
      { id: 2, name: 'How I met Your Mother' },
      { id: 3, name: 'Modenr Family' }
    ];

    this.selectedSerie = this.series[0];
  }

  onChange(serieId: any): void {
    this.selectedSerie = this.series.find(serie => serie.id == serieId);
  }
}

See the complete example here: http://plnkr.co/edit/OOYx3LiN1pO3qffKn7lq

Upvotes: 2

Related Questions