2017-10-10 8 views
3

入力ぼかしまたはEnterキーを押したときにのみUIの一部を更新するはずのフォームで作業しています。私は反応型のファンであり、私は正しい方法が何であるか把握しようとしています。これまでのところ、私は反応型フォームにはあまりにも多くの答えが見つかりませんでした。それらのほとんどはテンプレート駆動フォームに焦点を当てています。反応式をトリガする方法valueChangesサブスクリプションのみのサブスクリプションとアンギュラーキーの入力2

<form [formGroup]="fooForm"> 
    <table class="list expiries"> 
      <td *ngFor="let value of foo; let i = index"> 
       <input type="text" [formControlName]="foo[i]" 
        (blur)="refreshAllFooRelatedData()" 
        (keydown)="refreshAllFooRelatedDataOnEnter($event)"> 
      </td> 
    </table> 
</form> 

{{ debugTemplate() }} 

はこのまともですダイナミックフォームの値が実行時に変更

Formコンポーネント(ノー予測可能提出名)

import { Component, Input, Output, EventEmitter, 
    ChangeDetectionStrategy } from '@angular/core' 
import { FormBuilder, FormGroup, FormControl } from '@angular/forms' 
import { Observable } from "rxjs/Observable" 
import { DEBUG } from '../../../../config/config' 
import * as Debug from 'debug' 

// Interfaces 
import { Foo } from '../../interfaces/foo' 

// Services 
import { FooService } from '../../services/foo.service' 

// Debug 
const debugOff = (...any) => { }, debug = Debug('app:FooCmp') 

@Component({ 
    selector: 'foo-data-cmp', 
    templateUrl: './foo.data.cmp.html', 
    changeDetection: ChangeDetectionStrategy.OnPush, 
    styleUrls: ['./foo.data.cmp.css'] 
}) 
export class FooDataCmp { 

    private _foo: Foo[] = null 
    @Input('foo') 
    set foo(foo: Foo[]) { 
     this._foo = foo 
     DEBUG.input && debug('Input foo:', this._foo) 
    } 
    get foo(): Foo[] { 
     return this._foo 
    } 

    // Forms 
    public fooForm: FormGroup 
    public fooForm$: Observable<any> 
    private updatedFoo: any[] // Updated form values 

    // Subscriptions 
    private subscriptions: any[] = [] 

    constructor(
     private formBuilder: FormBuilder, 
     private fooService: FooService, 
    ) { 
     DEBUG.constr && debug('Construct FooDataCmp') 
    } 

    ngOnInit() { 
     DEBUG.init && debug('Initialise FooDataCmp') 

     // Form 
     this.initFooForm() 
     this.subcribeToFormChanges() 
    } 

    ngOnDestroy() { 
     DEBUG.destroy && debug('Destroy FooDataCmp') 
     this.subscriptions.forEach(sub => sub.unsubscribe()) 
    } 

    private initFooForm() { 
     DEBUG.cmp && debug('Initialise foo form') 

     // Build the form 
     this.fooForm = this.formBuilder.group(this._foo) 

     // Prevent undefined error at first keystroke 
     this.updatedFoo = this._foo 
    } 

    private subcribeToFormChanges() { 
     this.fooForm$ = this.fooForm.valueChanges 
     let sub = this.fooForm$.subscribe(fooForm => { 
      DEBUG.cmp && debug('Form changes fooForm', fooForm) 
      this.updatedFoo = fooForm 
     }) 
     this.subscriptions.push(sub) 
    } 

    /** 
    * <!> Important step in the data update process 
    * Update state store. 
    * Other services/components are subscribed to the state store itself 
    */ 
    public refreshAllFooRelatedData() { 
     DEBUG.cmp && debug('Refresh all foo related data') 
     DEBUG.cmp && debugOff('Updated foo', this.updatedFoo) 
     this.fooService.refreshAllFooRelatedData(this.updatedFoo) 
    } 

    public refreshAllFooRelatedDataOnEnter (e: KeyboardEvent) { 
     if (e.keyCode !== 13) {return} 
     DEBUG.cmp && debug('Refresh all foo related data (on enter)') 
     DEBUG.cmp && debugOff('Updated foo', this.updatedFoo) 
     this.fooService.refreshAllFooRelatedData(this.updatedFoo) 
    } 

    public debugTemplate() { 
     DEBUG.render && debug('Render FooDataCmp') 
    } 

} 

フォームテンプレート:私はこれまでのところ、このような何かを得ました私はいくつかのトリックを欠いていますか?私の質問は、これが正しい方法であるかどうかです。私はこのタスクを処理するためのいくつかのフォームAPIオプションを見つけることを期待しています。私のアプローチはフォームの上に構築することでしたが、このタスクに利用可能なものがあれば完全なフォームapiを使用することになります

+0

*前に同様のシナリオに遭遇してきたこれはまともなソリューションです。私たちは何が好きなら...?*あなたが求めていますまたは、これはあなたのために働いていないのですか?もしそうなら、どこに問題がありますか?反応的なフォームは非常にうまくいきます(ドキュメント)(https://angular.io/guide/reactive-forms)。 [フォームコントロール](https://angular.io/api/forms/FormControl)もあります。 –

+0

私の質問は、これが正しい方法であるかどうかです。私は、このタスクを処理するためのいくつかのフォームAPIオプションを見つけるために尽力してきました。私のアプローチはフォームの上に構築することでしたが、このタスクに利用できるものがあれば、完全なフォームapiを使用します。 –

答えて

1

blurとenterイベントをサブジェクトに結合してvaluechangeとマージできますObservable、それはぼかしまたは入力時に値を発生させるだけです。私は完全にコードにちょうどアイデアをテストしていないと私は

// component 
 
this.updateField=new Subject() 
 

 
this.form.get('yourfield').valueChanges.withLatestFrom(updateField).map(res=>res[0]).subscribe() 
 

 
//html 
 
<input (blur)="updateField($event)" (keydown)="$event.keyCode == 13?updateField($event):false"/>

+0

これはきちんとしたアイデアです!私は何かがより良くできることを知っていた。ありがとう!実際、今私は目が覚めていないことを実感しています...私が変更を行うと更新されます。オブザーバブルFtw! :D –

関連する問題