2016-11-29 8 views
6

次のフォームフィールドは正常に動作しています。これにより、フィールドに入力して貼り付けたときに、fooObj.expDateがリアルタイムで正常に更新され、検証が行われることを意味します。私はこれを自分自身に明白にするための事前タグを持っています。角度2のフィールドをプログラムで更新する

<pre>{{fooObj.someDate | json}}</pre> 

    <div class="form-group inline-form__input"> 
    <label for="someDate">Some Date</label> 
    <input tabindex="2" 
      type="tel" 
      class="form-control" 
      maxlength="7" 
      placeholder="MM/YY" 
      formControlName="someDate" 
      name="someDate" 
      [(ngModel)]="fooObj.someDate" 
      someDate> 
    </div> 

しかし、私はこの分野でそのsomeDateディレクティブを持っています。このディレクティブはペースト・イベントをインターセプトします。それは、pasteイベントをキャンセルし、入力のいくつかの空想の書式設定を行い、その後、これを行います:

target.valueは私someDateフィールドです。値は入力ボックス内でうまく更新されます(入力内の画面上で変化します)。ただし、fooObj.someDateは更新されず、検証は行われません。例えば。タイムアウトで目標値を設定しても、キー/ペースト/その他のJavaScriptイベントを入力するのと同じ検証/オブジェクトの更新は行われません。

角度docsは、この上で言って多くの有用な必要はありません。

角度アップデートバインディング(したがって画面)アプリは、このようなキーストロークなどの非同期イベントに応答して何かをする場合にのみ。この例のコードは、可能な限り最短のテンプレートステートメントである数字0にkeyupイベントをバインドします。ステートメントは何も役に立たないが、Angularの要求を満たし、Angularが画面を更新するようにする。

このフィールドのディレクティブからフィールドの更新をどのようにトリガーしますか?

編集:コードを使用することによって、コメントに推奨されているように、私は要素にイベントをトリガーしようとしたが、私の要素にここで見つける:How can I trigger an onchange event manually?

は罰金実行しますが、更新するフィールドを強制するものではありません:

また、ここでは、 "正常な"アクションをkeyDownなどとトリガしない合成イベントのアイデアを得ています(私は実際に誤読しているか、またはこのユースケースで間違っていると思っていますが、ペーストイベントを再発行しようとしています):https://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces

注: 合成イベントにはデフォルトアクションがありません。言い換えれば、上記のスクリプトはペーストイベントを発生させますが、データは実際にドキュメントに貼り付けられることはありません。

+0

あなたはそれに 'input'イベントをトリガしてみましたか? – Meir

+0

@Meir:以前に貼り付けイベントを再発行しようとしました。私はこれが通常のonClick/paste/keyup/whateverと同じ方法をトリガーしない "合成"イベントを作成すると言われました。 (http://stackoverflow.com/questions/40848003/set-preventdefault-back-to-false-on-javascript-event)。私はonChange()を試して、通常のkeyUpイベントを発行するつもりです。 – VSO

+0

また、 'input'イベントを試してください。 – Meir

答えて

2

あなたのディレクティブの詳細はわかりませんが、私はあなたの意図を推測できます。

<input tabindex="2" 
      type="tel" 
      class="form-control" 
      maxlength="7" 
      placeholder="MM/YY" 
      formControlName="someDate" 
      name="someDate" 
      someDate /> 
form.html

:で起動するには、我々は我々のコントロールのvalueChanges観測可能に加入し、ちょうど過度の書き込みやチェックを回避するために、コントロールに直接結合する双方向を避けるつもりです

form.ts

私たちが購読している場所です

constructor() { 
    this.myForm = new FormGroup({ 
     someDate: new FormControl(''), 
    }); 

    this.myForm.controls['someDate'].valueChanges.subscribe(
     value => this.fooObj.someDate = value; 
    ); 
    } 

一部-date.directive.ts

ディレクティブは、コントロールに値を書き込むとvalueChangesへのサブスクリプションは、我々のモデルを更新します。これはペーストイベントと他のすべてのイベントで機能します(対象とするイベントを制限することができますが、少なくとも貼り付けが確実に行われたかったと思います)。

@Directive({ 
    selector: '[someDate]' 
}) 
export class SomeDateDirective{ 
    constructor(private el: ElementRef, private control : NgControl) { 

    } 

    @HostListener('input',['$event']) onEvent($event){ 
    $event.preventDefault(); 
    let data = $event.clipboardData.getData('text'); 
    setTimeout(() => { 
     this.control.control.setValue(data.toUpperCase()); 
    }, 3000); 
    } 
} 

のみonpasteイベントをキャプチャするpaste代わりのinputに変更します。 preventDefault()でちょっと変わってしまえば、しばらく入力が消えてしまいます。ここで

はplunkerです:http://plnkr.co/edit/hsisILvtKErBBOXECt8t?p=preview

+0

WHOO!これは私が必要とするものです。それを実装していないが、それが動作することを確認してください。タイは大急ぎで倒錯しています。 – VSO

+1

@VSOうれしい私は助けることができました。 – silentsod

関連する問題