Виявити зміну на ngModel на виділеному тегу (Angular 2)


97

Я намагаюся знайти зміну на 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

Відповіді:


234

Оновлення :

Відокремте прив'язку події та властивостей:

<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)">

і тоді вам не доведеться оновлювати модель у обробнику подій, але я вважаю, що це спричиняє запуск двох подій, тому, ймовірно, це менш ефективно.


Стара відповідь, перш ніж виправити помилку в beta.1:

Створіть змінну локального шаблону та вкладіть (change)подію:

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

plunker

Див. Також Як я можу отримати новий вибір у "вибрати" у Angular 2?


1
То який сенс, ngModelякщо я просто прив’язую нову змінну, що називається item? Хіба не сенс загортати ngModelв дужки, щоб придбати слухачі подій, то чому ми вводимо нову змінну?
люкс

2
@lux, так, гарне запитання. selectedItem- це наші зв’язані дані, які NgModel оновлює для нас автоматично, але ... він не повідомляє нас про зміни, що часто є достатньо хорошим (перегляди та подібні оновляться), але, очевидно, це недостатньо для вашого випадку використання. В іншому запитанні SO, на яке я посилався, я описую, як я намагався використовувати (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, чи можете ви вказати мені документацію щодо цього, щоб я міг поділитися з рештою моєї команди розробників?
Neil S

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.