Evento di cambio angolare 2 ad ogni pressione di un tasto


282

L'evento change viene chiamato solo dopo che il focus dell'ingresso è cambiato. Come posso farlo in modo che l'evento si attivi ad ogni pressione dei tasti?

<input type="text" [(ngModel)]="mymodel" (change)="valuechange($event)" />
{{mymodel}}

La seconda associazione cambia ad ogni pressione di tasto tra i tasti.

Risposte:


474

Ho appena usato l'input dell'evento e ha funzionato bene come segue:

nel file .html:

<input type="text" class="form-control" (input)="onSearchChange($event.target.value)">

nel file .ts:

onSearchChange(searchValue: string): void {  
  console.log(searchValue);
}

Buona Per me va bene.
Godekere,

questo è esattamente quello che stavo cercando
Francesco Borzi,

come ritardare per qualche tempo?
Mahmoud Hboubati,

Funziona alla grande! Grazie
Vedha Peri,

Funziona benissimo, grazie mille
Rahul Lad,

193

Utilizzare ngModelChangesuddividendo la [(x)]sintassi nei suoi due pezzi, ovvero il databinding delle proprietà e il binding degli eventi:

<input type="text" [ngModel]="mymodel" (ngModelChange)="valuechange($event)" />
{{mymodel}}
valuechange(newValue) {
  mymodel = newValue;
  console.log(newValue)
}

Funziona anche con il tasto Backspace.


5
Ma quando si utilizza la banana in una sintassi box, cambia solo il modello, ma non è possibile agganciare qualcosa all'evento change.
Giora Guttsait,

4
Questa è un'ottima risposta per la migliore associazione di dati bidirezionale. Dovrebbe essere la risposta accettata!
Tk1993,

4
la chiave backspace non aggiorna il modello
Karan Garg,

4
Quella soluzione è corretta. Tuttavia, tenere presente che ngModelChange viene attivato PRIMA degli aggiornamenti del valore. Quindi il 'newValue' in questo esempio contiene il modello SENZA il tasto che hai appena premuto, quindi non hai il modello aggiornato lì. Se si desidera avere il valore del modello più recente, utilizzare l'evento (keyup).
dave0688,

1
@SateeshKumarAlli quale versione di Angular hai? Per me rileva backspace in Angular 6.1.3
Jette il

96

L'evento (keyup) è la soluzione migliore.

Vediamo perché:

  1. (modifica) come hai menzionato, si innesca solo quando l'ingresso perde la messa a fuoco, quindi è di utilità limitata.
  2. (pressione dei tasti) si attiva alla pressione dei tasti ma non si attiva in determinati tasti come il backspace.
  3. (keydown) si attiva ogni volta che un tasto viene premuto. Quindi ritarda sempre di 1 carattere; poiché ottiene lo stato dell'elemento prima della registrazione della sequenza di tasti.
  4. (keyup) è la soluzione migliore in quanto si innesca ogni volta che un evento push di tasti viene completato, quindi include anche il personaggio più recente.

Quindi (keyup) è il più sicuro da usare perché ...

  • registra un evento ad ogni sequenza di tasti a differenza dell'evento (modifica)
  • include i tasti che (pressione tasti) ignora
  • non ha alcun ritardo a differenza dell'evento (keydown)

4
Come menzionato in una delle risposte, l'evento di input funziona davvero bene. keyupè sicuramente una delle opzioni più sicure, tuttavia l' inputevento è un passo avanti keyup. keyupdiversamente input, non funziona se il valore della casella di testo viene modificato in qualsiasi altro modo, ad es. rilegatura.
planet_hunter

1
Sagar, grazie mille. Questa dovrebbe essere la risposta accettata in quanto è l'unica ad affrontare effettivamente (change)una soluzione alternativa e quindi alcuni. La risposta accettata fa davvero schifo!
Cody

c'è qualche motivo particolare per cui vorresti farlo (ngModelChange)?
SnailCoil,

1
Questa dovrebbe essere la risposta accettata e più sicura poiché è nativa e ti dà il pieno controllo ed è molto espressiva, perché tutti quelli che la leggono sanno esattamente quando l'evento viene lanciato.
Florian Leitgeb,

1
@ThariqNugrohotomo No, non lo sarebbe. Usa (input) se stai cercando qualcosa del genere.
Sagar

39
<input type="text" [ngModel]="mymodel" (keypress)="mymodel=$event.target.value"/>
{{mymodel}}

10
funziona, ma stranamente il tasto backspace non viene riconosciuto come un tasto premuto?
Daniel,

22
Potresti voler usare keydowno keyupinvece. Alcuni tasti non si accendono keypress. Vedere anche stackoverflow.com/questions/4843472/...
Günter Zöchbauer

Ho provato il keydown, il keyup e il cambio di eventi ma quando l'input è w il gestore di eventi mi segnala una stringa vuota; quando l'input è il gestore dell'evento mi segnala w come input. Puoi spiegare perché questo comportamento?
previsto il

Usa il tasto. L'input non è ancora cambiato al momento del keydown.
Günter Zöchbauer,

1
È strano, ma sto ricevendo un ritardo di input in questo caso in cui il valore non contiene il valore digitato fino alla successiva pressione del tasto.
Matt Eland,

25

Un modo diverso di gestire tali casi è usare formControl e iscriversi a valueChangesquando viene inizializzato il componente, che ti consentirà di utilizzare gli operatori rxjs per requisiti avanzati come l'esecuzione di richieste http, applicare un rimbalzo fino a quando l'utente finisce di scrivere una frase, prendere l'ultimo valore e omettere precedente, ...

import {Component, OnInit} from '@angular/core';
import { FormControl } from '@angular/forms';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';

@Component({
  selector: 'some-selector',
  template: `
    <input type="text" [formControl]="searchControl" placeholder="search">
  `
})
export class SomeComponent implements OnInit {
  private searchControl: FormControl;
  private debounce: number = 400;

  ngOnInit() {
    this.searchControl = new FormControl('');
    this.searchControl.valueChanges
      .pipe(debounceTime(this.debounce), distinctUntilChanged())
      .subscribe(query => {
        console.log(query);
      });
  }
}

2
Questo è perfetto. Ciò mantiene basso il rumore quando si usa questo per richieste http asincrone. Inoltre imposta già i listener di eventi change. Brillante! Grazie!
Hewstone,

Sono contento che abbia aiutato. Grazie @hewstone
Salem Ouerdani il

1
In caso di più controlli, lo stesso codice può essere applicato conFormGroup
Vikash Kumar il

20

L'evento segreto che mantiene sincrono ngModel angolare è l' input della chiamata dell'evento . Quindi la migliore risposta alla tua domanda dovrebbe essere:

<input type="text" [(ngModel)]="mymodel" (input)="valuechange($event)" />
{{mymodel}}

Lo fa per me @AndreiDiaconescu
KhoPhi il

L'evento (input) non è supportato nei browser Edge e IE. Qual è l'alternativa per questo nel browser Edge?
Sudhakar,

6
<input type="text" (keypress)="myMethod(myInput.value)" #myInput />

archivio .ts

myMethod(value:string){
...
...
}

Benvenuto in SO Ulric, spiega come il tuo codice risolve il problema.
CPHPython

4

Quello che stai cercando è

<input type="text" [(ngModel)]="mymodel" (keyup)="valuechange()" />
{{mymodel}}

Quindi fai quello che vuoi con i dati accedendo al limite this.mymodelnel tuo file .ts.


2

Nel mio caso, la soluzione è:

[ngModel]="X?.Y" (ngModelChange)="X.Y=$event"

1

Per i moduli reattivi, è possibile iscriversi alle modifiche apportate a tutti i campi o solo a un determinato campo.

Ricevi tutte le modifiche di un FormGroup:

this.orderForm.valueChanges.subscribe(value => {
    console.dir(value);
});

Ottieni il cambio di un campo specifico:

this.orderForm.get('orderPriority').valueChanges.subscribe(value => {
    console.log(value);
  });

0

Ho usato il keyup su un campo numerico, ma oggi ho notato in Chrome che l'input ha i pulsanti su / giù per aumentare / diminuire il valore che non sono riconosciuti dal keyup.

La mia soluzione è usare il keyup e cambiare insieme:

(keyup)="unitsChanged[i] = true" (change)="unitsChanged[i] = true"

I test iniziali indicano che funziona correttamente, verranno inviati di nuovo in caso di bug riscontrati dopo ulteriori test.

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.