11

In Angular 1.x, you could bind ngModel to a model for a select control:

<select ng-model="selectedPerson" 
   ng-options="person as person.name for person in people">
</select>

When an option is selected, the selectedPerson model will point to the person model that the user selected.

Is there a way to do the same thing in Angular2?

I've tried the following with no luck:

<select [(ngModel)] = "selectedPerson"> 
     <option *ngFor="#person of people"> {{ person.name }}</option>
</select>

I've also tried:

<select [(ngModel)] = "selectedPerson"> 
     <option *ngFor="#person of people" [value]="person"> {{ person.name }}</option>
</select>

In the first attempt, selectedPerson model references person.name rather than the person object. And in the second attempt, it is referencing an object, which doesn't appear to be a JSON object.

Any ideas what I am doing wrong? Is this even possible?

Michael Kang
  • 52,003
  • 16
  • 103
  • 135

2 Answers2

4

You could implement a <select> inside a form using the FormBuilder directive:

import { FormBuilder, Validators } from '@angular/forms';

export class LoginPage {

  constructor(form: FormBuilder) {
    this.cities = ["Shimla", "New Delhi", "New York"]; // List of cities
    this.loginForm = form.group({
      username: ["", Validators.required],
      password: ["", Validators.required],
      city: ["", Validators.required] // Setting the field to "required"
    });
  }

  login(ev) {
    console.log(this.loginForm.value); // {username: <username>, password: <password>, city: <city>}
  }

}

In your .html:

<form [ngFormModel]="loginForm" (submit)="login($event)">

    <input type="text" ngControl="username">
    <input type="password" ngControl="password">
    <select ngControl="city">
        <option *ngFor="#c of cities" [value]="c">{{c}}</option>
    </select>
    <button block type="submit" [disabled]="!loginForm.valid">Submit</button>

</form>

Official Documentation

daniel.gindi
  • 3,457
  • 1
  • 30
  • 36
Avijit Gupta
  • 5,676
  • 3
  • 20
  • 35
  • This isn't what I'm after. Using ngControl still binds to the value of the input control, rather than the model. When a drop down is selected, I am trying to bind selectedPerson to the model { name:'' } rather than just name. Try updating your example to use models where a city is an object: { name: }. You will see that loginForm.city is just a string. – Michael Kang Dec 27 '15 at 22:24
  • @pixelbits Why don't you simply set `this.selectedPerson = {}` inside your constructor, and then `[(ngModel)] = "selectedPerson.name"` with a `[value]=person.name` in the options? This will result in: `selectedPerson: {name: ""}`. – Avijit Gupta Dec 28 '15 at 06:59
  • That is not the same as binding to a model. I could be retrieving these objects from a DB. I'm looking for the equivalent of ng-options="person as person.name for person in people" – Michael Kang Dec 28 '15 at 07:14
1

I have the same issue trying to pass an object as selected value to a ngModel. An alternative solution I see is to use a stringified version of the object passing to a string, but that is very dirty.

In the end I have decided to create a separate index in the object which gets passed to the ngModel. This I use to select the Object and do the action.

Also issue raised in : https://github.com/angular/angular/issues/4843 and How to use select/option/NgFor on an array of objects in Angular2

Community
  • 1
  • 1
TomG
  • 597
  • 5
  • 12