如何检测选择标签(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,显示selectedItem
在onChange()
触发时没有更新,因此我们似乎需要那个本地模板变量。
@lux #
或 #item
在我们的例子中是 local 引用。因此,为什么我们能够在那里做item.change
。
@lux,我已经描述了挂钩的方法:绑定到ngModelChange
自定义事件。问题是,对于 <select>
,每次更改都会触发此事件两次。【参考方案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 应用程序上对用户进行身份验证后的动态角色和权限
如何使用 promql 在新标签上对两个 Prometheus 时间序列进行分组?