web-dev-qa-db-ja.com

Angular 2入力ディレクティブ変更フォームコントロール値

テキストボックスの入力値を変更する単純なAngular 2ディレクティブがあります。モデル駆動型フォームアプローチを使用していることに注意してください。

@Directive({
  selector: '[appUpperCase]'
})
export class UpperCaseDirective{

  constructor(private el: ElementRef, private control : NgControl) {

  }

  @HostListener('input',['$event']) onEvent($event){
    console.log($event);
    let upper = this.el.nativeElement.value.toUpperCase();
    this.control.valueAccessor.writeValue(upper);

  }

}

Domは正しく更新されますが、モデルは他のすべてのキーストロークの後に更新されます。 plnkr を見てください。

14
Mike Lunn

私は以前にこれに遭遇し、頭を掻いたままにされたので、これは私を興奮させます。

問題を再検討する必要があるのは、this.control.valueAccessor.writeValue(upper)を変更することです。ControlValueAccessorは、コントロール自体ではなくDOM要素に明示的に書き込み、代わりに

 this.control.control.setValue(upper);

これにより、コントロールの値が変更され、ページとコントロールのプロパティの両方に正しく反映されます。 https://angular.io/docs/ts/latest/api/forms/index/ControlValueAccessor-interface.html

ControlValueAccessorは、入力コントロールを表すDOM要素に新しい値を書き込む操作を抽象化します。

これは分岐したプランカーです: http://plnkr.co/edit/rllNyE07uPhUA6UfiLkU?p=preview

32
silentsod

私はこのようなものを探していましたが、プロジェクトでコードを試したところ、@ silentsodによって提供された上記の作業例に従ってthis.el.nativeElement.value.toUpperCase()という行でエラーが発生しました。

私はコードを次のように修正しました:

let str:string = this.control.value;
this.control.control.setValue(str.toUpperCase());

これは分岐したプランカーです: http://plnkr.co/edit/uf6udp7mQYmnKX6hGPpR?p=preview

0
gocasco