Wykryj zmianę w ngModel na zaznaczonym tagu (Angular 2)

97

Próbuję wykryć zmianę ngModelw <select>tagu. W Angular 1.x możemy rozwiązać ten problem za pomocą opcji $watchon ngModellub używając ngChange, ale jeszcze nie rozumiem, jak wykryć zmianę ngModelw Angular 2.

Pełny przykład : 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);
  }

}

Jak widać, jeśli wybierzemy inną wartość z listy rozwijanej, nasze ngModelzmiany i interpolowane wyrażenie w widoku odzwierciedlają to.

Jak mogę otrzymać powiadomienie o tej zmianie w mojej klasie / kontrolerze?

luks
źródło
1
możesz chcieć zachować niektóre dodatkowe komentarze pod kontrolą; nie chcesz, aby to pytanie zostało oflagowane jako rant w przebraniu. stackoverflow.com/help/dont-ask .
Claies

Odpowiedzi:

235

Aktualizacja :

Oddziel powiązania zdarzenia i właściwości:

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

Możesz również użyć

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

i wtedy nie musiałbyś aktualizować modelu w module obsługi zdarzeń, ale uważam, że powoduje to uruchomienie dwóch zdarzeń, więc prawdopodobnie jest mniej wydajne.


Stara odpowiedź, zanim naprawili błąd w wersji beta.1:

Utwórz zmienną szablonu lokalnego i dołącz (change)wydarzenie:

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

plunker

Zobacz także Jak mogę uzyskać nowy wybór w opcji „wybierz” w Angular 2?

Mark Rajcok
źródło
1
Więc jaki jest sens, ngModeljeśli po prostu wiążę nową zmienną o nazwie item? Czy nie chodzi o zawijanie ngModelnawiasów w celu pozyskania detektorów zdarzeń, więc dlaczego wprowadzamy nową zmienną?
lux
2
@lux, tak, dobre pytanie. selectedItemto nasze powiązane dane, które NgModel aktualizuje automatycznie dla nas, ale ... nie powiadamia nas o zmianach, co często jest wystarczająco dobre (widoki i takie będą aktualizowane), ale oczywiście nie jest to wystarczające dla twojego przypadku użycia. W drugim pytaniu SO, do którego się odwołałem, opisuję, w jaki sposób próbowałem użyć (ngModelChange)powiadomienia o zmianach, ale jest ono wywoływane dwukrotnie przy każdej zmianie. Nie wiem, czy to błąd, czy nie. W każdym razie dodanie (change)powiązania zdarzenia wydaje się rozwiązać problem.
Mark Rajcok
Zaktualizowałem również plunker, który pokazuje, że selectedItemnie jest aktualizowany podczas onChange()pożaru, dlatego wydaje się, że potrzebujemy tej zmiennej lokalnego szablonu.
Mark Rajcok
@lux #lub #itemw naszym przypadku jest odniesieniem lokalnym . Dlatego możemy to zrobić item.change.
Mark Pieszak - Trilon.io
@lux, już opisałem sposób podłączenia: bind do ngModelChangezdarzenia niestandardowego. Problem polega na <select>tym, że to zdarzenie jest uruchamiane dwukrotnie przy każdej zmianie.
Mark Rajcok,
12

Natknąłem się na to pytanie i podam odpowiedź, której użyłem i zadziałałem całkiem nieźle. Miałem pole wyszukiwania, które filtrowało i tworzyło tablice obiektów, aw moim polu wyszukiwania użyłem rozszerzenia(ngModelChange)="onChange($event)"

w moim .html

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

następnie w moim component.ts

reSearch(newValue: string) {
    //this.searchText would equal the new value
    //handle my filtering with the new value
}
Logan H.
źródło
5
Po prostu FYI, gdy jest powiązany z ngModelChange, $eventnie jest zdarzeniem DOM . Jest to raczej bieżąca wartość elementu formularza, który jest łańcuchem znaków dla elementu wejściowego.
Mark Rajcok
@MarkRajcok, czy możesz wskazać mi dokumentację dotyczącą tego, abym mógł podzielić się nią z resztą mojego zespołu programistów?
Neil S