ตรวจจับการเปลี่ยนแปลงของ ngModel บนแท็กที่เลือก (Angular 2)


99

ฉันกำลังพยายามตรวจพบการเปลี่ยนแปลงngModelใน<select>แท็ก ใน Angular 1.x เราอาจแก้ปัญหานี้ด้วยการ$watchเปิดngModelหรือใช้ngChangeแต่ฉันยังไม่เข้าใจวิธีตรวจจับการเปลี่ยนแปลงngModelใน Angular 2

ตัวอย่างเต็ม : 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);
  }

}

ดังที่เราเห็นหากเราเลือกค่าที่แตกต่างจากดรอปดาวน์ngModelการเปลี่ยนแปลงของเราและนิพจน์ที่ถูกแทรกในมุมมองจะสะท้อนถึงสิ่งนี้

ฉันจะรับแจ้งการเปลี่ยนแปลงนี้ในชั้นเรียน / คอนโทรลเลอร์ได้อย่างไร


1
คุณอาจต้องการเก็บความคิดเห็นเพิ่มเติมไว้ในการตรวจสอบ คุณไม่ต้องการให้คำถามนี้ถูกตั้งค่าสถานะว่าเป็นการพูดจาโผงผาง stackoverflow.com/help/dont-ask
Claies

คำตอบ:


238

อัปเดต :

แยกเหตุการณ์และการเชื่อมโยงคุณสมบัติ:

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

คุณยังสามารถใช้

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

จากนั้นคุณจะไม่ต้องอัปเดตโมเดลในตัวจัดการเหตุการณ์ แต่ฉันเชื่อว่าสิ่งนี้ทำให้สองเหตุการณ์เริ่มทำงานดังนั้นจึงอาจมีประสิทธิภาพน้อยกว่า


คำตอบเก่าก่อนที่จะแก้ไขข้อบกพร่องในเบต้า 1:

สร้างตัวแปรเทมเพลตโลคัลและแนบ(change)เหตุการณ์:

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

plunker

ดูเพิ่มเติมฉันจะรับตัวเลือกใหม่ใน "เลือก" ใน Angular 2 ได้อย่างไร


1
แล้วจะเป็นngModelอย่างไรถ้าฉันผูกตัวแปรใหม่ที่เรียกว่าitem? ไม่ใช่จุดngModelในการใส่วงเล็บเพื่อให้ได้ผู้ฟังเหตุการณ์ดังนั้นทำไมเราจึงแนะนำตัวแปรใหม่
ลักซ์

2
@lux ใช่คำถามที่ดี selectedItemเป็นข้อมูลที่ถูกผูกไว้ของเราซึ่ง NgModel จะอัปเดตให้เราโดยอัตโนมัติ แต่ ... มันไม่ได้แจ้งให้เราทราบถึงการเปลี่ยนแปลงซึ่งมักจะดีพอ (จำนวนการดูและข้อมูลดังกล่าวจะอัปเดต) แต่เห็นได้ชัดว่านี่ไม่ดีพอสำหรับกรณีการใช้งานของคุณ ในคำถามอื่น ๆ ที่ฉันอ้างถึงฉันอธิบายถึงวิธีที่ฉันพยายามใช้(ngModelChange)เพื่อรับการแจ้งเตือนการเปลี่ยนแปลง แต่จะถูกเรียกสองครั้งสำหรับการเปลี่ยนแปลงแต่ละครั้ง ฉันไม่รู้ว่านั่นเป็นบั๊กหรือไม่ อย่างไรก็ตามการเพิ่มการ(change)ผูกเหตุการณ์ดูเหมือนจะช่วยแก้ปัญหาได้
Mark Rajcok

นอกจากนี้ฉันยังอัปเดต plunker ซึ่งแสดงselectedItemว่าไม่ได้รับการอัปเดตเมื่อเริ่มonChange()ทำงานดังนั้นดูเหมือนว่าเราต้องการตัวแปรเทมเพลตภายในเครื่อง
Mark Rajcok

@lux #หรือ#itemในกรณีของเราคือข้อมูลอ้างอิงในท้องถิ่น ดังนั้นทำไมเราไม่สามารถที่จะทำitem.changeมี
Mark Pieszak - Trilon.io

@lux ฉันได้อธิบายวิธีการเชื่อมต่อกับngModelChangeเหตุการณ์ที่กำหนดเองแล้ว ปัญหาคือ<select>เหตุการณ์นี้จะเริ่มทำงานสองครั้งสำหรับการเปลี่ยนแปลงทุกครั้ง
Mark Rajcok

12

ฉันเจอคำถามนี้และจะส่งคำตอบว่าใช้แล้วได้ผลดี ฉันมีช่องค้นหาที่กรองและจัดเรียงวัตถุและในช่องค้นหาของฉันฉันใช้ไฟล์(ngModelChange)="onChange($event)"

ในไฟล์ .html

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

จากนั้นในไฟล์ component.ts

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

5
เพียง FYI เมื่อผูกพันกับngModelChange, $eventไม่ได้เป็น DOM เหตุการณ์ แต่เป็นค่าปัจจุบันขององค์ประกอบฟอร์มซึ่งเป็นสตริงสำหรับองค์ประกอบอินพุต
Mark Rajcok

@MarkRajcok คุณช่วยชี้ให้ฉันดูเอกสารสำหรับเรื่องนี้เพื่อให้ฉันสามารถแบ่งปันกับทีม dev ที่เหลือของฉันได้ไหม
Neil S

1
@NeilS ที่ใกล้ที่สุดคือangular.io/docs/ts/latest/guide/template-syntax.html#!#ngModel
Mark Rajcok
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.