Phát hiện thay đổi đối với ngModel trên một thẻ đã chọn (Angular 2)


97

Tôi đang cố gắng phát hiện sự thay đổi ngModeltrong <select>thẻ. Trong Angular 1.x, chúng tôi có thể giải quyết vấn đề này bằng $watchbật ngModelhoặc bằng cách sử dụng ngChange, nhưng tôi vẫn chưa hiểu cách phát hiện thay đổi đối với ngModelAngular 2.

Ví dụ đầy đủ : 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);
  }

}

Như chúng ta có thể thấy, nếu chúng ta chọn một giá trị khác từ menu thả xuống, các ngModelthay đổi của chúng ta và biểu thức nội suy trong chế độ xem sẽ phản ánh điều này.

Làm cách nào để nhận được thông báo về sự thay đổi này trong lớp học / bộ điều khiển của tôi?


1
bạn có thể muốn kiểm tra một số nhận xét bổ sung; bạn không muốn câu hỏi này bị gắn cờ như một lời ngụy biện. stackoverflow.com/help/dont-ask .
Yêu cầu

Câu trả lời:


234

Cập nhật :

Tách sự kiện và ràng buộc tài sản:

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

Bạn cũng có thể sử dụng

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

và sau đó bạn sẽ không phải cập nhật mô hình trong trình xử lý sự kiện, nhưng tôi tin rằng điều này gây ra hai sự kiện để kích hoạt, vì vậy nó có thể kém hiệu quả hơn.


Câu trả lời cũ, trước khi họ sửa một lỗi trong bản beta.1:

Tạo một biến mẫu cục bộ và đính kèm một (change)sự kiện:

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

plunker

Xem thêm Làm cách nào để có được lựa chọn mới trong "select" trong Angular 2?


1
Vì vậy, vấn đề là gì ngModelnếu tôi chỉ ràng buộc một biến mới được gọi là item? Mục đích của việc gói gọn ngModeltrong dấu ngoặc đơn là để có được các trình nghe sự kiện, vậy tại sao chúng ta lại giới thiệu một biến mới?
lux

2
@lux, câu hỏi hay đấy. selectedItemlà dữ liệu liên kết của chúng tôi, được NgModel cập nhật tự động cho chúng tôi, nhưng ... nó không thông báo cho chúng tôi về các thay đổi, điều này thường đủ tốt (các lượt xem và tương tự sẽ cập nhật), nhưng rõ ràng điều này không đủ tốt cho trường hợp sử dụng của bạn. Trong câu hỏi SO khác mà tôi đã tham khảo, tôi mô tả cách tôi đã cố gắng sử dụng (ngModelChange)để nhận thông báo về các thay đổi, nhưng nó được gọi hai lần cho mỗi thay đổi. Tôi không biết đó có phải là một lỗi hay không. Dù sao, việc thêm một (change)ràng buộc sự kiện dường như sẽ giải quyết được vấn đề.
Mark Rajcok

Ngoài ra, tôi đã cập nhật plunker cho thấy nó selectedItemkhông được cập nhật khi onChange()kích hoạt, do đó có vẻ như chúng tôi cần biến mẫu cục bộ đó.
Mark Rajcok

@lux #hoặc #itemtrong trường hợp của chúng tôi là một tham chiếu cục bộ . Do đó tại sao chúng tôi có thể làm được item.changeở đó.
Mark Pieszak - Trilon.io

@lux, tôi đã mô tả cách để kết nối: liên kết với ngModelChangesự kiện tùy chỉnh. Vấn đề là, <select>sự kiện này xảy ra hai lần cho mỗi lần thay đổi.
Mark Rajcok

12

Tôi đã tình cờ gặp câu hỏi này và tôi sẽ gửi câu trả lời mà tôi đã sử dụng và làm việc khá tốt. Tôi có một hộp tìm kiếm lọc và mảng các đối tượng và trên hộp tìm kiếm của mình, tôi đã sử dụng(ngModelChange)="onChange($event)"

trong tôi .html

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

sau đó trong tôi component.ts

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

5
Chỉ FYI, khi liên kết với ngModelChange, $eventkhông phải là Sự kiện DOM . Thay vào đó, nó là giá trị hiện tại của phần tử biểu mẫu, là một chuỗi cho một phần tử đầu vào.
Mark Rajcok

@MarkRajcok, bạn có thể vui lòng chỉ cho tôi tài liệu về vấn đề này để tôi có thể chia sẻ với những người còn lại trong nhóm phát triển của mình không?
Neil S

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.