I am attempting to detect a change on ngModel
in a <select>
tag. In Angular 1.x, we might solve this with a $watch
on ngModel
, or by using ngChange
, but I’ve yet to understand how to detect a change to ngModel
in Angular 2.
Full Example: http://plnkr.co/edit/9c9oKH1tjDDb67zdKmr9?p=info
import {Component, View, Input, } from 'angular2/core'; import {FORM_DIRECTIVES} from 'angular2/common'; @Component({ selector: 'my-dropdown' }) @View({ directives: [FORM_DIRECTIVES], template: ` <select [ngModel]="selection" (ngModelChange)="onChange($event, selection)" > <option *ngFor="#option of options">{{option}}</option> </select> {{selection}} ` }) export class MyDropdown { @Input() options; selection = 'Dog'; ngOnInit() { console.log('These were the options passed in: ' + this.options); } onChange(event) { if (this.selection === event) return; this.selection = event; console.log(this.selection); } }
As we can see, if we select a different value from the dropdown, our ngModel
changes, and the interpolated expression in the view reflects this.
How do I get notified of this change in my class/controller?
Advertisement
Answer
Update:
Separate the event and property bindings:
<select [ngModel]="selectedItem" (ngModelChange)="onChange($event)">
onChange(newValue) { console.log(newValue); this.selectedItem = newValue; // don't forget to update the model here // ... do other stuff here ... }
You could also use
<select [(ngModel)]="selectedItem" (ngModelChange)="onChange($event)">
and then you wouldn’t have to update the model in the event handler, but I believe this causes two events to fire, so it is probably less efficient.
Old answer, before they fixed a bug in beta.1:
Create a local template variable and attach a (change)
event:
<select [(ngModel)]="selectedItem" #item (change)="onChange(item.value)">
See also How can I get new selection in “select” in Angular 2?