2017-01-30 3 views
2

私はngModelChangeイベントを呼び出すようにしようとしているだけで、私は今ngModelChangeはngModelChange.emit()から発射さではないにもかかわらず、キー操作で呼び出されます

this.ngModelChange.emit(data) 

とそれを呼び出すとき、それは私がヒットするたびに呼び出されています私のキーボードのキーと前のコマンドでそれを呼び出すとき。どうして?

私は渡された型の属性に応じて異なるタイプの入力を作成する 'Feild'コンポーネントを持っています。それらの1つはJQueryで作成したオートコンプリートコンポーネントです。角度をつけて動作させるために、値を渡すためのコンポーネントを作成しました。

フィールド成分:

import { Component, Input, Output, EventEmitter } from '@angular/core'; 

@Component({ 
    selector: 'field', 
    template: `<div class="field"> 
       <div class="fieldTitle" *ngIf="text">{{text}}</div> 
       <div class="fieldValue" *ngIf="type"> 
        <input *ngIf="type == 'text'" type="text" [ngModel]="ngModel" (ngModelChange)="onChange($event)" [name]="name" ngDefaultControl/> 
        <autocomplete *ngIf="type == 'autocomplete'" [link]="link" [mapping]="mapping" [ngModel]="ngModel" (ngModelChange)="onChange($event)" [name]="name" ngDefaultControl></autocomplete> 
       </div> 
      </div>` 
}) 
export class Field{ 
    @Input() text: string; 
    @Input() type: string; 
    @Input() ngModel: any; 
    @Input() name: string; 
    @Input() mapping: string; 
    @Input() link: string; 

    @Output() ngModelChange = new EventEmitter(); 

    constructor(){ 

    } 

    onChange(e){ 
     this.ngModel = e; 
     this.ngModelChange.emit(e); 
    } 
} 

オートコンプリート成分:

import { Component, Input, ViewChild, Output, EventEmitter} from '@angular/core'; 

@Component({ 
    selector: 'autocomplete', 
    template: `<div #autocomplete class='autoComplete'></div>` 
}) 
export class AutoComplete{ 
    @Input() ngModel: any; 
    @Input() link: string; 
    @Input() mapping: string; 

    @ViewChild('autocomplete') content: any; 

    @Output() ngModelChange = new EventEmitter(); 
    @Output() select = new EventEmitter(); 

    constructor(){ 

    } 
    ngAfterViewInit(){ 
     var ctrl = this; 
     var options = { 
      link: this.link, 
      mapping: this.mapping, 
      data: this.ngModel, 

      onSelect: function(data: any){ 
       ctrl.ngModel = data; 
       ctrl.ngModelChange.emit(data); 
       ctrl.select.emit({data: data}); 
      }, 
      setData: function(e : any){ 
       ctrl.ngModel = e; 
       ctrl.ngModelChange.emit(e); 
      } 
     } 

     for(var key in options) { 
      if(options[key] === undefined){ 
       delete options[key]; 
      } 
     } 

     $(this.content.nativeElement).autoComplete(options); 
    } 
} 

私のオートコンプリートは、いくつかの他のdivおよびスタイルで入力を生成します。内部に何かを入力すると、データのリストをフィルタリングし、入力内の文字列をマッチングするものだけを表示します。結果をクリックすると、クリックしたデータが設定されます。キーを押すたびにsetData(未定義)を呼び出してデータを削除し、clickイベントではonSelect(data)関数を呼び出します。その部分はうまく動作します。

オートコンプリートコンポーネントからの関数setData()の前に、入力の文字列内の値ですべてのキーストロークでFieldコンポーネントのonChange()関数が呼び出されます。どうすればonChange()への不要な呼び出しを削除できますか?事前

ありがとうございます例TOR plunkerにてご確認行くことができます:https://plnkr.co/edit/jAVIupQ2R1Vm1y9YHoLI?p=preview

コンソールで見れば、あなたは文字列や未定義が表示されます。文字列は入力と同じもので、自動補完が返すものは未定義です。未定義は良いですが、文字列ではありません。それを動作させるにはしばらく時間がかかりました。これは、FormsModuleをインポートするとすぐに発生します。 NgModelで動作する他の種類の入力を使用するのでFormsModuleが必要です。

答えて

1

まず:

ngModelChangengModelなどの予約された角度の言葉を使用しないでください。

予期しない動作につながるようですね!第二に

あなたautocomplete正しく動作していない、それは現在の値を設定しません。

はそれを修正:https://plnkr.co/edit/2H0GRSp3ktJWoMSWDe7S?p=preview

サード:

obj.search = function (reinitialize) { 
    obj.options.data = obj.input[0].value; // NEW !! 
     if (reinitialize === true) { 
     //obj.options.data = undefined; // ?!?!?!? WHY ?? 

をここで働くデモだ

ngModelサポートを実装する方が良いだろう。あなたはここで説明するように、ControlValueAccessorを実装する必要があります。

https://stackoverflow.com/a/41935754/3631348

+0

のonChangeが二回呼び出されるので、それは働いていません。文字列のパラメータでkeypressを1回、this.ngModelChange.emit(data)から2回目を選択します。 –

+0

プランナーで再現できますか? – mxii

+0

私はplunkerといくつかの説明を追加するために私の質問を更新しました。 –

関連する問題