如何检测选择标签(Angular 2)上对 ngModel 的更改?

Posted

技术标签:

【中文标题】如何检测选择标签(Angular 2)上对 ngModel 的更改?【英文标题】:How do I detect change to ngModel on a select tag (Angular 2)? 【发布时间】:2016-03-28 02:17:23 【问题描述】:

我正在尝试在 <select> 标记中检测 ngModel 的更改。在 Angular 1.x 中,我们可能会在 ngModel 上使用 $watch 或使用 ngChange 来解决这个问题,但我还没有理解如何在 Angular 2 中检测到 ngModel 的更改。

完整示例: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 会发生变化,并且视图中的插值表达式会反映这一点。

如何在我的类/控制器中收到有关此更改的通知?

【问题讨论】:

您可能希望保留一些额外的 cmets;你不希望这个问题被标记为变相的咆哮。 ***.com/help/dont-ask. 【参考方案1】:

更新

分离事件和属性绑定:

<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

另见How can I get new selection in "select" in Angular 2?

【讨论】:

如果我只是绑定一个名为item 的新变量,那么ngModel 的意义何在?将ngModel 括在括号中不就是获取事件监听器的意义吗,那我们为什么要引入一个新变量呢? @lux,是的,好问题。 selectedItem 是我们的绑定数据,NgModel 会自动为我们更新,但是......它不会通知我们更改,这通常已经足够好(视图等会更新),但显然这对您来说还不够好用例。在我引用的另一个 SO 问题中,我描述了我如何尝试使用 (ngModelChange) 来获取更改通知,但每次更改都会调用两次。我不知道这是否是一个错误。无论如何,添加(change) 事件绑定似乎可以解决问题。 另外,我更新了 plunker,显示selectedItemonChange() 触发时没有更新,因此我们似乎需要那个本地模板变量。 @lux ##item 在我们的例子中是 local 引用。因此,为什么我们能够在那里做item.change @lux,我已经描述了挂钩的方法:绑定到ngModelChange 自定义事件。问题是,对于 &lt;select&gt;,每次更改都会触发此事件两次。【参考方案2】:

我偶然发现了这个问题,我将提交我使用过并且工作得很好的答案。我有一个过滤和对象数组的搜索框,在我的搜索框中我使用了(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

【讨论】:

仅供参考,当绑定到ngModelChange 时,$event 不是 DOM Event。而是表单元素的当前值,它是输入元素的字符串。 @MarkRajcok 你能给我指点这方面的文档吗,以便我可以与我的开发团队的其他成员分享? @NeilS,最接近的是angular.io/docs/ts/latest/guide/template-syntax.html#!#ngModel

以上是关于如何检测选择标签(Angular 2)上对 ngModel 的更改?的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 2/4 应用程序上对用户进行身份验证后的动态角色和权限

组件选择器标签上的Angular 2样式?

如何检测指令元素是不是*未*在 Angular 中单击

如何使用 promql 在新标签上对两个 Prometheus 时间序列进行分组?

Angular 2 路由已弃用:如何检测 CanActivate?

如何检测 Angular 2 反应/动态表单的一个元素发生的变化?