我有一个textarea的代码,它与ngModel工作得很好并且直播更新,但我希望my-custom-directive知道绑定到这个textarea的模型何时发生变化。
如何在my-custom-directive中检测此textarea的模型更改?
<textarea my-custom-directive class="green" [(ngModel)]="customertext"></textarea>
答案 0 :(得分:10)
<强>更新强>
@Directive({
selector: 'xyz',
host: {'(ngModelChange)': 'doSomething($event)'}
})
export class Xyz {
doSomething(event){... }
}
<强>原始强>
<textarea my-custom-directive class="green" [(ngModel)]="customertext"
(ngModelChange)="doSomething($event) "></textarea>
[(ngModel)]="customertext"
是
的缩写形式[ngModel]="customertext" (ngModelChange)="customertext=$event"
答案 1 :(得分:8)
尝试添加到您的指令:
@HostListener('input') onInput() {
console.log('on input');
}
答案 2 :(得分:5)
有多种方法可以检测更改,还取决于组件中定义的 ChangeDetectionStrategy 。
为了提供帮助,我将简化答案并专注于与 ngModel 指令进行交互的Reactive Extensions(Rx)方式,因为它功能强大,并且具有最佳的集成度角度2变化检测引擎,性能明智。
首先,我们需要强调NgModel绑定到Element的值,所有更改都通过您订阅的 EventEmitter 传播。 EventEmitter 是一个Angular2类型,它是一个Rx主题,它基本上是一个可以&#34;传输&#34; (发出)事件/数据,也可以对数据做出反应&#34;收到&#34;。所以在Rx中它是一个Observable和一个Observer。
另外值得一提的是&#34; ngOnChanges&#34;接收处理变更事件的处理程序的ngModel上的方法,但我们将重点关注Rx方法。
因此,我们需要访问该Observable并订阅它,太棒了!
为了获得访问权限,我们使用依赖注入,只需声明我们想要在我们的指令的构造函数中获取NgModel。
现在我们还需要小心,我们需要确保我们确实得到NgModel,否则我们会有错误。
我们可以通过创建一个强制一个NgModel元素的指令选择器来静默地执行它,例如:&#39; selector&#39;:&#39; [myCustomDirective] [ngModel]&# 39;,现在如果ngModel不是元素的一部分,它就不会匹配我们的指令选择器。
或者,我们可以制造噪音而不是默默地出去,我们将依赖注入标记为 @Optional ,如果它为null,我们可以抛出一个明确的异常,说明丢失了什么。 如果我们不能将其标记为 @Optional ,则会抛出一条关于缺失依赖项的通用消息,但它确定但不好。
现在,举个例子:
import {Directive, Optional} from 'angular2/core';
import {NgModel}from 'angular2/common';
@Directive({
selector: '[myCustomDirective][ngModel]'
})
export class MyCustomDirective {
constructor(@Optional() public model: NgModel) {
if (!model)
throw new Error ("myCustomDirective requires ngModel.");
// this code should be in a designated functions...
// register to incoming changes to the model
// we can also transform values..., for example take only distinct values...
// this.model.update.distinctUntilChanged()...
let subscription = this.model.update.subscribe((newValue) => {
// Changes happen here, do something with them...
// note that the value of this.model is still the old value
// The local parameter "newValue" holds the new value.
});
// We can also change the value of the model:
this.model.update.emit('something...');
}
}
希望有所帮助。
答案 3 :(得分:4)
有不同的方法来检测 Agnular2 中的变化,并根据您使用它们的条件,它们将具有上行和下行。
Angular允许您将所有标准事件绑定到包括--option argument
的元素。所以在这种情况下作为表单元素,您只需使用:
change
该活动将是原生JavaScript事件,因此您可以获取<textarea my-custom-directive class="green" [(ngModel)]="customertext" (change)="doSomething($event)"></textarea>
,originalEvent
,并获取更改属性及其值:
target
当您想要观察表单中所有/部分元素的更改时,这非常有效。使用散列引用也很简单就是这种方法。
答案 4 :(得分:1)
将model
(检测到更改开启)作为Input()
传递给指令,然后使用ngOnChange()
,如下所示。
import {Directive, ElementRef, Input, OnChanges} from '@angular/core';
@Directive({
selector: '[myCustomDirective]'
})
export class MyCustomDirective implements OnChanges {
@Input() myCustomDirective: any;
constructor(private el: ElementRef) {}
ngOnChanges(changes) {
if (changes.myCustomDirective) {
console.log('chnaged');
}
}
}
以下是如何将模型作为输入传递给指令:
<textarea [myCustomDirective]="customertext" class="green" [(ngModel)]="customertext"></textarea>