Rileva la modifica a ngModel su un tag di selezione (Angular 2)


97

Sto tentando di rilevare una modifica ngModelin un file<select> tag. In Angular 1.x, potremmo risolvere questo problema con un $watchon ngModelo utilizzando ngChange, ma devo ancora capire come rilevare una modifica ngModelin Angular 2.

Esempio completo : 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);
  }

}

Come possiamo vedere, se selezioniamo un valore diverso dal menu a discesa, le nostre ngModelmodifiche e l'espressione interpolata nella vista lo riflettono.

Come ricevo la notifica di questo cambiamento nella mia classe / controller?


1
potresti voler tenere sotto controllo alcuni dei commenti extra; non vuoi che questa domanda venga contrassegnata come uno sproloquio mascherato. stackoverflow.com/help/dont-ask .
Claies

Risposte:


234

Aggiornamento :

Separare le associazioni di eventi e proprietà:

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

Potresti anche usare

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

e quindi non dovresti aggiornare il modello nel gestore di eventi, ma credo che questo causi l'attivazione di due eventi, quindi probabilmente è meno efficiente.


Vecchia risposta, prima che risolvessero un bug nella beta.1:

Crea una variabile di modello locale e allega un (change)evento:

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

plunker

Vedi anche Come posso ottenere una nuova selezione in "seleziona" in Angular 2?


1
Allora qual è il punto ngModelse sto solo vincolando una nuova variabile chiamata item? Non è il punto di racchiudere ngModeltra parentesi per acquisire ascoltatori di eventi, quindi perché stiamo introducendo una nuova variabile?
lux

2
@lux, sì, bella domanda. selectedItemsono i nostri dati vincolati, che NgModel aggiorna automaticamente per noi, ma ... non ci informa delle modifiche, il che spesso è abbastanza buono (visualizzazioni e simili si aggiorneranno), ma ovviamente questo non è abbastanza buono per il tuo caso d'uso. Nell'altra domanda SO a cui ho fatto riferimento, descrivo come ho provato a utilizzare (ngModelChange)per ricevere una notifica delle modifiche, ma viene chiamata due volte per ogni modifica. Non so se sia un bug o meno. Ad ogni modo, l'aggiunta di un'associazione di (change)eventi sembra risolvere il problema.
Mark Rajcok

Inoltre, ho aggiornato il plunker che mostra che selectedItemnon viene aggiornato quando viene attivato onChange(), quindi sembra che abbiamo bisogno di quella variabile del modello locale.
Mark Rajcok

@lux il #o #itemnel nostro caso è un riferimento locale . Ecco perché siamo in grado di farlo item.changelì.
Mark Pieszak - Trilon.io

@lux, ho già descritto il modo di agganciarsi: bind ngModelChangeall'evento personalizzato. Il problema è che, con <select>, questo evento si attiva due volte per ogni modifica.
Mark Rajcok

12

Mi sono imbattuto in questa domanda e presenterò la mia risposta che ho usato e ha funzionato abbastanza bene. Avevo una casella di ricerca che filtrava e un array di oggetti e nella mia casella di ricerca ho usato il file(ngModelChange)="onChange($event)"

nel mio .html

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

poi nel mio component.ts

reSearch(newValue: string) {
    //this.searchText would equal the new value
    //handle my filtering with the new value
}

5
Solo FYI, se vincolato a ngModelChange, $eventnon è un evento DOM . Piuttosto è il valore corrente dell'elemento form, che è una stringa per un elemento di input.
Mark Rajcok

@MarkRajcok puoi indicarmi la documentazione per questo, così posso condividerla con il resto del mio team di sviluppo?
Neil S

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.