如何从angular2中的指令检测输入字段的模型变化

时间:2016-01-31 10:45:31

标签: angular

我有一个textarea的代码,它与ngModel工作得很好并且直播更新,但我希望my-custom-directive知道绑定到这个textarea的模型何时发生变化。

如何在my-custom-directive中检测此textarea的模型更改?

  <textarea my-custom-directive class="green" [(ngModel)]="customertext"></textarea>

5 个答案:

答案 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>