Обнаружить изменение ngModel в теге выбора (Angular 2)

97

Я пытаюсь обнаружить изменение ngModelв <select>теге. В Angular 1.x мы могли бы решить эту проблему с помощью $watchвключения ngModelили использования ngChange, но я еще не понял, как обнаружить изменение ngModelв Angular 2.

Полный пример : 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);
  }

}

Как мы видим, если мы выберем другое значение из раскрывающегося списка, наши ngModelизменения и интерполированное выражение в представлении это отражают.

Как я могу получить уведомление об этом изменении в моем классе / контроллере?

люкс
источник
1
возможно, вы захотите держать некоторые дополнительные комментарии под контролем; Вы не хотите, чтобы этот вопрос был помечен как замаскированная тирада. stackoverflow.com/help/dont-ask .
Claies

Ответы:

235

Обновление :

Разделите привязки событий и свойств:

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

Вы также можете использовать

<select [(ngModel)]="selectedItem" (ngModelChange)="onChange($event)">

и тогда вам не нужно будет обновлять модель в обработчике событий, но я считаю, что это приводит к срабатыванию двух событий, поэтому это, вероятно, менее эффективно.


Старый ответ, до того, как они исправили ошибку в beta.1:

Создайте локальную переменную шаблона и прикрепите (change)событие:

<select [(ngModel)]="selectedItem" #item (change)="onChange(item.value)">

plunker

См. Также Как я могу получить новое выделение в «select» в Angular 2?

Марк Райкок
источник
1
Так какой смысл, ngModelесли я просто привязываю новую переменную с именем item? Разве не ngModelстоит заключать в круглые скобки для получения слушателей событий, так зачем же мы вводим новую переменную?
люкс
2
@lux, да, хороший вопрос. selectedItem- это наши связанные данные, которые NgModel обновляет автоматически для нас, но ... он не уведомляет нас об изменениях, что часто бывает достаточно хорошо (представления и тому подобное будут обновляться), но, очевидно, этого недостаточно для вашего варианта использования. В другом вопросе SO, на который я ссылался, я описываю, как я пытался использовать его (ngModelChange)для получения уведомлений об изменениях, но он вызывается дважды для каждого изменения. Не знаю, ошибка это или нет. В любом случае, добавление (change)привязки к событию решает проблему.
Марк Райкок
Кроме того, я обновил плункер, который показывает, что selectedItemон не обновляется при onChange()срабатывании, поэтому, похоже, нам нужна эта локальная переменная шаблона.
Марк Райкок
@lux #или #itemв нашем случае - это местная ссылка. Вот почему мы можем item.changeтам работать .
Марк Пешак - Trilon.io
@lux, я уже описывал способ подключения: привязка к ngModelChangeнастраиваемому событию. Проблема в том, что <select>это событие запускается дважды при каждом изменении.
Марк Райкок
12

Я наткнулся на этот вопрос и отправлю свой ответ, который я использовал и работал довольно хорошо. У меня было поле поиска с фильтрами и массивом объектов, а в поле поиска я использовал(ngModelChange)="onChange($event)"

в моем .html

<input type="text" [(ngModel)]="searchText" (ngModelChange)="reSearch(newValue)" placeholder="Search">

тогда в моем component.ts

reSearch(newValue: string) {
    //this.searchText would equal the new value
    //handle my filtering with the new value
}
Логан Х
источник
5
Просто FYI, при связывании ngModelChange, $eventне DOM Event . Скорее, это текущее значение элемента формы, которое является строкой для элемента ввода.
Марк Райкок
@MarkRajcok, не могли бы вы указать мне документацию по этому поводу, чтобы я мог поделиться с остальной частью моей команды разработчиков?
Neil S
1
@NeilS, ближайший - angular.io/docs/ts/latest/guide/template-syntax.html#!#ngModel
Марк Райкок