Acara perubahan sudut 2 pada setiap penekanan tombol

282

Acara perubahan hanya dipanggil setelah fokus input berubah. Bagaimana saya bisa membuatnya sehingga acara ini menyala pada setiap penekanan tombol?

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

Ikatan kedua berubah pada setiap penekanan tombol btw.

daniel
sumber

Jawaban:

474

Saya hanya menggunakan input acara dan bekerja dengan baik sebagai berikut:

dalam file .html:

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

dalam file .ts:

onSearchChange(searchValue: string): void {  
  console.log(searchValue);
}
Ramy Feteha
sumber
Bagus Bekerja untukku.
Godekere
ini persis apa yang saya cari
Francesco Borzi
bagaimana kita menunda untuk beberapa waktu?
Mahmoud Hboubati
Bagus sekali! Terima kasih
Vedha Peri
Bekerja Hebat, Terima kasih banyak
Rahul Lad
193

Gunakan ngModelChangedengan memecah [(x)]sintaks menjadi dua bagian, yaitu penyatuan data properti dan pengikatan acara:

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

Ini juga berfungsi untuk tombol backspace.

Mark Rajcok
sumber
5
Tetapi ketika menggunakan pisang dalam sintaksis kotak, itu hanya mengubah model, tetapi Anda tidak dapat mengaitkan sesuatu pada acara perubahan.
Giora Guttsait
4
Itu jawaban yang bagus untuk pengikatan data dua arah terbaik. Seharusnya jawaban yang diterima!
Tk1993
4
kunci backspace tidak memperbarui model
Karan Garg
4
Solusi itu benar. Namun, perlu diketahui bahwa ngModelChange dipecat SEBELUM pembaruan nilai. Jadi 'nilai baru' dalam contoh ini berisi model TANPA kunci yang baru saja Anda tekan - sehingga Anda tidak memiliki model yang diperbarui di sana. Jika Anda ingin memiliki nilai model terbaru, gunakan acara (keyup).
dave0688
1
@SateeshKumarAlli versi Angular apa yang Anda miliki? Bagi saya itu mendeteksi backspace di Angular 6.1.3
Jette
96

Acara (keyup) adalah taruhan terbaik Anda.

Mari kita lihat mengapa:

  1. (ubah) seperti yang Anda sebutkan hanya memicu ketika input kehilangan fokus, karenanya penggunaan terbatas.
  2. (penekanan tombol) memicu pada penekanan tombol tetapi tidak memicu pada penekanan tombol tertentu seperti backspace.
  3. (keydown) memicu setiap kali kunci ditekan ke bawah. Karenanya selalu tertinggal 1 karakter; karena mendapat status elemen sebelum keystroke didaftarkan.
  4. (keyup) adalah taruhan terbaik Anda karena memicu setiap kali acara push key telah selesai, maka ini juga termasuk karakter terbaru.

Jadi (keyup) adalah yang paling aman untuk digunakan karena ...

  • mendaftarkan suatu acara pada setiap penekanan tombol tidak seperti acara (perubahan)
  • termasuk kunci yang (ditekan tombol) mengabaikan
  • tidak memiliki lag tidak seperti acara (keydown)
Sagar
sumber
4
Seperti disebutkan dalam salah satu jawaban, input event berfungsi dengan sangat baik. keyuppasti salah satu opsi paling aman, bagaimanapun, inputacara adalah selangkah lebih maju keyup. keyuptidak seperti input, tidak berfungsi jika nilai kotak teks diubah dengan cara lain misalnya mengikat.
planet_hunter
1
Sagar, terima kasih banyak. Ini harus menjadi Jawaban yang Diterima karena itu adalah satu-satunya yang benar-benar membahas di (change)samping solusi dan beberapa. Jawaban yang diterima benar-benar menyebalkan!
Cody
adakah alasan khusus Anda ingin melakukan ini (ngModelChange)?
SnailCoil
1
Ini harus menjadi jawaban yang diterima dan paling aman karena itu asli dan memberi Anda kontrol penuh dan itu sangat ekspresif, karena semua orang yang membacanya tahu persis kapan acara tersebut dipecat.
Florian Leitgeb
1
@ThariqNugrohotomo Tidak, tidak akan. Gunakan (input) jika Anda mencari sesuatu seperti itu.
Sagar
39
<input type="text" [ngModel]="mymodel" (keypress)="mymodel=$event.target.value"/>
{{mymodel}}
Günter Zöchbauer
sumber
10
berfungsi, tetapi anehnya tombol backspace tidak dikenali sebagai penekanan tombol?
daniel
22
Anda mungkin ingin menggunakan keydownatau keyupsebagai gantinya. Beberapa kunci tidak menyala keypress. Lihat juga stackoverflow.com/questions/4843472/…
Günter Zöchbauer
Saya telah mencoba keydown, keyup dan mengubah event tetapi ketika inputnya w event handler melaporkan kepada saya string kosong; ketika inputnya, kita pengendali event melaporkan kepada saya sebagai input. Bisakah Anda jelaskan mengapa perilaku ini?
renungkan
Gunakan penekanan tombol. Masukan belum berubah saat keydown.
Günter Zöchbauer
1
Ini aneh, tapi saya mendapatkan input lag di mana nilainya tidak mengandung nilai yang diketik sampai penekanan tombol berikutnya.
Matt Eland
25

Cara berbeda untuk menangani kasus tersebut adalah dengan menggunakan formControl dan berlangganan valueChangesketika komponen Anda diinisialisasi, yang akan memungkinkan Anda untuk menggunakan operator rxjs untuk persyaratan lanjutan seperti melakukan permintaan http, menerapkan debounce sampai pengguna selesai menulis kalimat, mengambil nilai terakhir dan hapus sebelumnya, ...

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);
      });
  }
}
Salem Ouerdani
sumber
2
Ini sempurna. Ini menjaga kebisingan mengobrol saat menggunakan ini untuk permintaan http async. Juga sudah menyiapkan perubahan acara pendengar. Cemerlang! Terima kasih!
hewstone
Senang itu membantu. Terima kasih @hewstone
Salem Ouerdani
1
Dalam hal beberapa kontrol, kode yang sama dapat diterapkan denganFormGroup
Vikash Kumar
20

Acara rahasia yang membuat ngModel tetap sinkron adalah input panggilan acara . Karenanya jawaban terbaik untuk pertanyaan Anda adalah:

<input type="text" [(ngModel)]="mymodel" (input)="valuechange($event)" />
{{mymodel}}
Emeka Obianom
sumber
Itu berlaku untuk saya @AndreiDiaconescu
KhoPhi
Acara (input) tidak didukung di browser Edge dan IE. Apa alternatif untuk ini di browser Edge?
Sudhakar
6
<input type="text" (keypress)="myMethod(myInput.value)" #myInput />

arsip .ts

myMethod(value:string){
...
...
}
Ulric Merguiço
sumber
Selamat datang di SO Ulric, tolong jelaskan bagaimana kode Anda memecahkan masalah.
CPHPython
4

Yang Anda cari adalah

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

Kemudian lakukan apa pun yang Anda inginkan dengan data dengan mengakses terikat this.mymodeldi file .ts Anda.

Sanket Berde
sumber
2

Dalam kasus saya, solusinya adalah:

[ngModel]="X?.Y" (ngModelChange)="X.Y=$event"
hatem htira
sumber
1

Untuk Formulir Reaktif, Anda dapat berlangganan perubahan yang dibuat untuk semua bidang atau hanya bidang tertentu.

Dapatkan semua perubahan dari FormGroup:

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

Dapatkan perubahan bidang tertentu:

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

Saya telah menggunakan keyup pada bidang angka, tetapi hari ini saya perhatikan di chrome input memiliki tombol naik / turun untuk menambah / mengurangi nilai yang tidak dikenali oleh keyup.

Solusi saya adalah dengan menggunakan keyup dan ubah bersama:

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

Tes awal menunjukkan ini berfungsi dengan baik, akan memposting kembali jika ada bug yang ditemukan setelah pengujian lebih lanjut.

pengguna9273992
sumber