2016-08-23 20 views
4

「TrimDirective」を実装して、入力フィールドから前後の空白を削除します。モデルドリブン/リアクティブフォームでディレクティブの入力値を変更する方法

私は入力フィールドの値を変更することができましたが、コンポーネントの新しい値はmyForm.valueChanges()になりません。

このplunkerを参照してください:http://plnkr.co/edit/ruzqCh?p=preview

ディレクティブが値を変更するとき、どのように私はformGroupの更新をトリガすることができますか?

テンプレート

<form [formGroup]="myForm"> 
    <input formControlName="name" trim> 
</form> 
latest value: -{{ latestValue }}- 

コンポーネント

@Component({ 
    selector: 'my-app', 
    templateUrl: 'app/app.html' 
}) 
export class AppComponent implements OnInit { 

    private myForm: FormGroup; 
    private latestValue: string; 

    ngOnInit() { 
    this.myForm = new FormGroup({ 
     name: new FormControl(), 
    }); 
    this.myForm.valueChanges.subscribe(v => this.latestValue = v.name) 
    } 
} 

ディレクティブ

@Directive({ 
    selector: '[trim]' 
}) 

export class TrimDirective { 

    private el: any; 

    constructor(
     el: ElementRef 
    ){ 
     this.el = el.nativeElement; 
    } 

    @HostListener('keypress') 
    onEvent() { 
     setTimeout(() => { // get new input value in next event loop! 
      let value: string = this.el.value; 
      if(value && (value.startsWith(' ') || value.endsWith(' '))) { 
       console.log('trim!'); 
       this.el.value = value.trim(); 
      } 
     },0); 
    } 
} 
+0

「onEvent」を「onKeyDown」 –

+2

@vikuに変更してみてください。これは問題ではありません。問題は 'this.el.value = value.trim();'は入力の値とDOMを更新しますが、angleの "model"は変更しないということです。どのようにディレクティブは 'detectChanges()'を強制するか、イベント/何か/何かを出すことができます(コンポーネント/ FormGroup/FormControlにアクセスしますか?) –

答えて

3

は、あなたが作成することができますndは、モデル値を更新するためにangleを指示するために要素上にchangeイベントをトリガーします。

let event: Event = document.createEvent("Event"); 
event.initEvent('input', true, true); 
Object.defineProperty(event, 'target', {value: this.elementRef.nativeElement, enumerable: true}); 
this.renderer.invokeElementMethod(this.elementRef.nativeElement, 'dispatchEvent', [event]); 
+0

私はテンプレート駆動型モデルに移行しました。 http://plnkr.co/edit/CLrA3b5v1V8LgszC3Vqi?p=preview –

+1

他の人に注意:ディレクティブのコンストラクタparamsに 'private renderer:Renderer'を追加し、 '@ angular/core';から' import {Renderer} 。最後に、関係のないもの:正しい「this」を使用していることを確認してください。これのコンテキストが変更されたイベントリスナーコールバック内でこの問題のさまざまな解決策を試してきたと私は恥ずかしく思います。ドワ –

関連する問題