テキストボックスの入力値を変更する単純な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 を見てください。
私は以前にこれに遭遇し、頭を掻いたままにされたので、これは私を興奮させます。
問題を再検討する必要があるのは、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
私はこのようなものを探していましたが、プロジェクトでコードを試したところ、@ 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