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.