2016-01-31 5 views
8

このコードはテキストエリア用ですが、ngModelとライブで更新していますが、my-custom-directiveがモデルバインドこのテキストエリアへの変更は変化しています。angular2の入力フィールドの入力フィールドのモデルの変化を検出する方法

my-custom-directiveでこのテキストエリアのモデル変更を検出するにはどうすればよいですか?

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

答えて

8

更新

@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

ありがとう、しかし述べたように、私は、ディレクティブはにそれを追加する必要があるとし、この変化を検出しないようにしたいですtextareaのhtmlコード –

+1

これは、同じモデルにバインドされている別のテキストエリアからモデルが変更された場合ではなく、テキストエリアに入力する場合にのみ機能します。 –

+1

"customertext"が '@Input()'の場合は?あなたのディレクティブに 'ngModelChange(changes)'を実装し、そこにコードを追加して変更に反応させることで、あなたが望むことができます。 –

5

変化を検出する複数の方法がありますが、それはまた、コンポーネントで定義されてChangeDetectionStrategyに依存します。

有用であるために、私は、答えを簡素化し、ngModel指令との相互作用の反応性拡張機能(Rx)の方法に焦点を当て、単にそれは超強力なので、角2変化検出エンジンと最高の統合されていますパフォーマンスは賢明です。

まず、NgModelがElementの値にバインドされ、すべての変更がサブスクライブするEventEmitterを介して伝達されることを強調する必要があります。 EventEmitterは、イベント/データを「送信」(送信)し、受信したデータに反応することができる基本的にオブジェクトであるRxサブジェクトであるAngular2タイプです。だから、RxにはObservableとObserverがあります。

また、変更イベントを処理するためのハンドラを受け取るngModelのngOnChangesメソッドもありますが、Rxアプローチに焦点を当てます。

私たちはObservableにアクセスし、それに登録する必要があります。

アクセスを得るには、ディペンデンシヨンのコンストラクタでNgModelを取得することを宣言するだけで、依存性注入を使用します。

ここでも注意する必要があります.NgModelを取得する必要があります。それ以外の場合はエラーが発生します。

我々は次のように、はNgModel要素を強制することを指示セレクタを作成することで、黙ってそれを行うことができます:「セレクタ」:ngModelは、要素の一部でない場合は「[myCustomDirective] [ngModel]」、今それは勝ちましたディレクティブのセレクタと一致しません。

また、私たちは静かに騒音を出すことはできません。従属性の注入を@Optionalとマークし、そのヌルが何か欠けているという明確な例外を投げることができます。 @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...'); 
    } 
} 

助け希望。

+0

これは、ngModelがテキストエリアで定義されている場合にのみ一致するのでしょうか?どちらの場合もどうやって説明しますか。 –

+0

カスタムディレクティブに使用されるDOM要素の属性として定義されたngModelが必要です。 –

+0

質問は、ngModelが存在するときのモデルの変更に関するものです。 ngModelまたはngControlなしの要素を使用して変更をリッスンする場合は、変更、キーアップなどのDomイベントにハンドラを登録する必要があります。 RxJsはObservable.fromEventなどのヘルパーを提供しています... ngModelはあなたのために行いますが、それがなくてもできます...もっと多くの仕事 –

3

Agnular2の変更を検出する方法はさまざまですが、使用している条件に応じて、上下に変化があります。 Angularでは、すべての標準イベントをchangeなどの要素にバインドできます。そのフォーム要素として、この場合には、単に使用することができます。

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

イベントはネイティブJavaScriptイベントとなり、あなたが得ることができるようにoriginalEventtarget、また変化特性とその値を取得します

これは、フォームのすべての/一部の要素の変更を監視する場合に特に効果的です。ハッシュリファレンスを使用しても、このアプローチはかなり簡単です。

4

は、あなたのディレクティブに追加してみてください。

@HostListener('input') onInput() { 
     console.log('on input'); 
} 
+0

これは実際に質問/問題に答える*唯一の回答です。私も同じ問題がありましたが、setTimeoutでテストしています。私は約5つの異なるアプローチ(ここでは他の答えも含む)を成功させずに試しましたが、これはAngular Material 2ライブラリがこの疑似バグを回避するために使用するものです。ありがとうございました!!Angular 4.1以上であることを指摘しておきますが、これはAngular 2以上で動作するはずです。 –

1

ディレクティブと以下のようなngOnChange()を使用するには、Input()としてmodel(上の検出の変更)を渡します。ここで

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> 
関連する問題