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?


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?


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
}

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.