เหตุการณ์การเปลี่ยนแปลงของ Angular 2 ในทุกการกดปุ่ม


282

เหตุการณ์การเปลี่ยนแปลงจะถูกเรียกเฉพาะหลังจากที่โฟกัสของอินพุตมีการเปลี่ยนแปลง ฉันจะทำให้เหตุการณ์นั้นเกิดขึ้นในทุกการกดปุ่มได้อย่างไร

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

การโยงครั้งที่สองจะเปลี่ยนในทุก ๆ การกดปุ่ม

คำตอบ:


473

ฉันใช้อินพุตเหตุการณ์และทำงานได้ดีดังต่อไปนี้:

ในไฟล์. html:

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

ในไฟล์. ts:

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

สิ่งที่ดี. ใช้งานได้สำหรับฉัน
Godekere

นี่คือสิ่งที่ฉันกำลังมองหา
Francesco Borzi

เราจะหน่วงเวลาอย่างไร
Mahmoud Hboubati

ใช้งานได้ดี! ขอบคุณ
Vedha Peri

ใช้งานได้ดีมากขอบคุณ
ราหุล Lad

193

ใช้ngModelChangeโดยการแบ่ง[(x)]ไวยากรณ์ออกเป็นสองส่วนคือการรวบรวมข้อมูลและการโยงเหตุการณ์:

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

มันใช้งานได้กับปุ่ม Backspace เช่นกัน


5
แต่เมื่อใช้ Banana ในไวยากรณ์กล่องมันจะเปลี่ยนรูปแบบเท่านั้น แต่คุณไม่สามารถขออะไรบางอย่างในเหตุการณ์การเปลี่ยนแปลง
Giora Guttsait

4
นั่นเป็นคำตอบที่ดีสำหรับการผูกข้อมูลสองทางที่ดีที่สุด ควรเป็นคำตอบที่ยอมรับได้!
Tk1993

4
ปุ่ม Backspace ไม่ได้อัปเดตโมเดล
Karan Garg

4
ทางออกนั้นถูกต้อง อย่างไรก็ตามโปรดทราบว่า ngModelChange จะเริ่มทำงานก่อนการอัพเดตค่า ดังนั้น 'newValue' ในตัวอย่างนี้จึงมีโมเดลโดยไม่ต้องกดปุ่ม - ดังนั้นคุณไม่มีรุ่นที่อัพเดท หากคุณต้องการมีค่ารุ่นล่าสุดให้ใช้เหตุการณ์ (keyup)
dave0688

1
@SateeshKumarAlli คุณมี Angular รุ่นใด สำหรับฉันมันตรวจจับ backspace ใน Angular 6.1.3
Jette

96

เหตุการณ์ (keyup) เป็นทางออกที่ดีที่สุดของคุณ

มาดูกันว่าทำไม:

  1. (เปลี่ยน)เช่นเดียวกับที่คุณกล่าวถึงทริกเกอร์เฉพาะเมื่ออินพุตสูญเสียโฟกัสจึงมีการใช้งาน จำกัด
  2. (keypress)ก่อให้เกิดการกดปุ่ม แต่ไม่ได้เรียกการกดแป้นบางอย่างเช่น backspace
  3. (keydown)ทริกเกอร์ทุกครั้งที่กดคีย์ ดังนั้นมักจะล่าช้าโดย 1 ตัวอักษร; ตามที่ได้รับสถานะองค์ประกอบก่อนการกดแป้นพิมพ์ลงทะเบียน
  4. (keyup)เป็นทางออกที่ดีที่สุดของคุณเป็นมันเป็นต้นเหตุของเวลาเหตุการณ์ผลักดันที่สำคัญได้เสร็จสิ้นทุกดังนั้นนี้ยังรวมถึงตัวละครล่าสุด

ดังนั้น (keyup) เป็นสิ่งที่ปลอดภัยที่สุดที่จะไปด้วยเพราะมัน ...

  • ลงทะเบียนเหตุการณ์ในทุกการกดแป้นไม่เหมือนเหตุการณ์ (เปลี่ยน)
  • รวมถึงปุ่มที่ (ปุ่มกด) ถูกละเว้น
  • ไม่มีความล่าช้าซึ่งแตกต่างจากเหตุการณ์ (keydown)

4
ดังที่กล่าวไว้ในหนึ่งในคำตอบเหตุการณ์ป้อนเข้าใช้งานได้ดีจริงๆ keyupคือการตรวจสอบหนึ่งในตัวเลือกที่ปลอดภัยที่สุด แต่เหตุการณ์เป็นขั้นตอนหนึ่งไปข้างหน้าของ input แตกต่างจากไม่ทำงานถ้าค่าของกล่องข้อความมีการเปลี่ยนแปลงด้วยวิธีอื่นเช่นผูกพัน keyupkeyupinput
planet_hunter

1
ซาก้าขอบคุณมาก นี่ควรเป็นคำตอบที่ได้รับการยอมรับเพราะมันเป็นเพียงคำตอบเดียวที่อยู่(change)ข้างการแก้ไขปัญหาชั่วคราวและบางข้อ คำตอบที่ยอมรับทั้งหมดดูด!
โคดี้

มีเหตุผลใดที่คุณต้องการทำเช่นนี้(ngModelChange)?
SnailCoil

1
นี่ควรเป็นคำตอบที่ได้รับการยอมรับและปลอดภัยที่สุดเนื่องจากเป็นเจ้าของภาษาและให้การควบคุมเต็มรูปแบบและมีความหมายมากเพราะทุกคนที่อ่านจะรู้ได้อย่างชัดเจนว่าเหตุการณ์ถูกยิงเมื่อใด
Florian

1
@ThariqNugrohotomo ไม่มันจะไม่ ใช้ (อินพุต) หากคุณกำลังมองหาบางอย่างเช่นนั้น
ซาก้า

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

10
ใช้งานได้ แต่คีย์ Backspace ไม่ได้รับการยอมรับว่าเป็นแป้นพิมพ์หรือไม่
daniel

22
คุณอาจต้องการที่จะใช้keydownหรือkeyupแทน keypressกุญแจบางคนก็ไม่ได้ยิง ดูstackoverflow.com/questions/4843472/…
GünterZöchbauer

ฉันลอง keydown, keyup และ change events แต่เมื่อ input เป็น w ตัวจัดการเหตุการณ์จะรายงานสตริงว่างให้ฉัน เมื่ออินพุตคือเราตัวจัดการเหตุการณ์รายงานให้ฉันเป็นอินพุต คุณกรุณาอธิบายว่าทำไมพฤติกรรมนี้
คาดการณ์

ใช้ปุ่มกด อินพุตยังไม่เปลี่ยนในการกดคีย์
GünterZöchbauer

1
มันแปลก แต่ฉันได้รับความล่าช้าในการป้อนข้อมูลในที่นี้ค่าไม่ได้มีค่าที่พิมพ์จนกว่าจะกดปุ่มต่อไป
Matt Eland

25

วิธีที่แตกต่างในการจัดการกรณีดังกล่าวคือการใช้formControlและสมัครสมาชิกvalueChangesเมื่อองค์ประกอบของคุณเริ่มต้นซึ่งจะช่วยให้คุณใช้ตัวดำเนินการrxjsสำหรับความต้องการขั้นสูงเช่นดำเนินการตามคำขอ HTTP ใช้การ debounce จนกว่าผู้ใช้จะเขียนประโยคเสร็จ และละเว้นก่อนหน้า ...

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
มันสมบูรณ์แบบ สิ่งนี้จะทำให้เสียงช่างพูดดังลงเมื่อใช้สิ่งนี้สำหรับคำขอ http ของ async นอกจากนี้ยังตั้งค่าตัวรับเหตุการณ์การเปลี่ยนแปลงแล้ว ยอดเยี่ยม! ขอบคุณ!
hewstone

ดีใจที่มันช่วย ขอบคุณ @hewstone
Salem Ouerdani

1
ในกรณีที่มีการควบคุมหลายตัวสามารถใช้รหัสเดียวกันกับFormGroup
Vikash Kumar

20

เหตุการณ์ความลับที่ช่วยให้การซิงโครเชิงมุม ngModel เป็นโทรเหตุการณ์การป้อนข้อมูล ดังนั้นคำตอบที่ดีที่สุดสำหรับคำถามของคุณควรเป็น:

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

@AndreiDiaconescu สำหรับฉัน
KhoPhi

เหตุการณ์ (อินพุต) ไม่รองรับในเบราว์เซอร์ Edge และ IE อะไรคือทางเลือกสำหรับสิ่งนี้ในเบราว์เซอร์ Edge
Sudhakar

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

เก็บถาวร. ts

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

ยินดีต้อนรับสู่ SO Ulric โปรดอธิบายว่ารหัสของคุณแก้ปัญหาได้อย่างไร
CPHPython

4

สิ่งที่คุณกำลังมองหาคือ

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

จากนั้นทำสิ่งที่คุณต้องการด้วยข้อมูลโดยเข้าถึงขอบเขตthis.mymodelในไฟล์. ts ของคุณ



1

สำหรับฟอร์มที่มีปฏิกิริยาคุณสามารถสมัครสมาชิกการเปลี่ยนแปลงที่ทำกับทุกฟิลด์หรือเฉพาะฟิลด์ที่ต้องการ

รับการเปลี่ยนแปลงทั้งหมดของ FormGroup:

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

รับการเปลี่ยนแปลงของฟิลด์ที่ระบุ:

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

0

ฉันใช้คีย์อัปในฟิลด์ตัวเลข แต่วันนี้ฉันสังเกตเห็นในโครเมี่ยมอินพุตมีปุ่มขึ้น / ลงเพื่อเพิ่ม / ลดค่าที่ไม่รู้จักโดยการกดปุ่ม

โซลูชันของฉันคือการใช้คีย์อัปและเปลี่ยนแปลงร่วมกัน:

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

การทดสอบเริ่มต้นบ่งบอกว่าใช้งานได้ดีจะโพสต์กลับหากพบข้อบกพร่องใด ๆ หลังจากการทดสอบเพิ่มเติม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.