web-dev-qa-db-ja.com

Angular FormControl入力内の2つの日付パイプ

動的に生成されたAngular 2 FormGroup入力フィールドを持つFormGroup。入力の一部は、Unixタイムスタンプとしてサーバーから取得される日付です。

私がやりたいことは:

  1. formGroupにデータが入力されたときに、Unixタイムスタンプを人間が読める形式に変換できるようにします。
  2. フォームの送信時に、日付の人間表現をUNIXタイムスタンプに変換します。

パート1はややシンプルで、Angularの日付パイプを次のように使用します。

_<input class="form-control" [formControlName]="question.key"
[value]="this.form.controls[this.question.key].value | date:'dd/MM/yyyy'">
_

This.formはFormGroupへの参照であり、this.questionは動的フォームに関する公式チュートリアルに基づくカスタムラッパークラスです。

https://angular.io/docs/ts/latest/cookbook/dynamic-form.html

パイプは常に入力値を変換しようとするため、日付入力をそのように変更しようとしても機能しません。したがって、パイプ「DatePipe」例外に対して無効な引数をスローしないと入力が使用できなくなります。

明確にするために、FormGroup.patchValue() apiを使用してフォームに入力し、FormGroup.getRawValue() apiを使用してフォームデータを送信します。

Angular 2の日付ピッカーコンポーネントを使用しようとしましたが、巨大なフォームがかなり遅くなったため、カスタムの日付ピッカーまたはjQueryに依存するウィジェットなしでそれを実行したいと思います。

前もって感謝します。

11
ktsangop

そのようなことを行う1つの方法は、 ControlValueAccessor を実装する入力用のコンポーネントを作成することです。

コントロールとネイティブ要素の間のブリッジ。

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

詳細については、 DefaultValueAccessor を参照してください。

このような何かがトリックを行う必要があります(テストされていません):

export const DATE_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => MyDateInput),
  multi: true
};

@Component({
    template:`<input #input (input)="onChange($event)" (blur)="touchCallback()" type="date" [attr.disabled]="disabled?true:null">`
    selector:"my-input",
    styles:[],
    providers:[DATE_VALUE_ACCESSOR]
})
export class MyDateInput implements ControlValueAccessor{
    @ViewChild("input")
    input:ElementRef;
    disabled=false;
    changeCallback=(data:any)=>{};
    touchCallback=()=>{};

    onChange(event){
        let timestamp=this.convertToTimestamp(event.target.value);
        this.changeCallback(timestamp);
    }

    convertToTimestamp(formatedDate){
        //TODO:implement
    }

    convertFromTimestamp(timestamp){
        //TODO:implement
    }

    writeValue(obj: any){
        let formatedDate=this.convertFromTimestamp(obj);
        this.input.nativeElement.value=formatedDate;
    }

    registerOnChange(fn: any){
        this.changeCallback=fn;
    }

    registerOnTouched(fn: any){
        this.touchCallback=fn;
    }

    setDisabledState(isDisabled: boolean){
        this.disabled=isDisabled;
    }
}

次のように使用できるはずです。

<my-input class="form-control" [formControlName]="question.key"></my-input>

または

<my-input [(ngModel)]="myModel"></my-input>
10
n00dl3