FormControl输入中的Angular 2日期管道 [英] Angular 2 date pipe inside a FormControl input

查看:269
本文介绍了FormControl输入中的Angular 2日期管道的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个动态生成的带有多个FormControl输入字段的Angular 2 FormGroup。一些输入是日期,这些日期是从服务器获取的unix时间戳。



我想要做的是:


  1. 能够翻译unix时间戳到人类可读的形式,
    当我的FormGroup被填充时,还有
  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依赖窗口小部件。



在此先感谢。

解决方案

执行此类操作的一种方法是为您的输入创建一个实现 ControlValueAccessor


控件和本地元素之间的桥梁。



ControlValueAccessor摘要将新值
写入表示输入控件的DOM元素的操作。

请参阅 DefaultValueAccessor 获取更多信息。


类似这样的事情应该可以做到这一点(未经测试):

  export const DATE_VALUE_ACCESSOR:any = {
提供:NG_VALUE_ACCESSOR,
useExisting:forwardRe f(()=> MyDateInput),
multi:true
};
$ b @Component({
template:`< input #input(input)=onChange($ event)(blur)=touchCallback()type =date[ attr.disabled] =disabled?true:null>`
选择器:my-input,
styles:[],
providers:[DATE_VALUE_ACCESSOR]
} )
export class MyDateInput实现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:执行
}

convertFromTimestamp(timestamp){
/ / TODO:执行
}

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:布尔值){
this.disabled = isDisabled;


$ / code>

那么你应该可以像这样使用它:


$ b

 < my-input class =form-control[formControlName] =question。键>< /我的输入> 

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


I have a dynamically generated Angular 2 FormGroup with multiple FormControl input fields. Some of the inputs are Dates, which are fetched from the server as unix timestamps.

What i would like to do is :

  1. to be able to translate the unix timestamp to a human readable form, when my FormGroup is populated, and also
  2. translate the human representation of the date to a unix timestamp when the form is submitted.

Part 1 is somewhat simple, using Angular's date pipe like this :

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

Where this.form is a reference to the FormGroup and this.question is a custom wrapper class based on the official tutorial about dynamic forms :

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

Trying to change the date input that way won't work because the pipe will constantly try to transform the input value, thus making the input unusable if not throwing an Invalid argument for pipe 'DatePipe' exception.

To clarify, i fill my form using the FormGroup.patchValue() api, and submit the form data using the FormGroup.getRawValue() api.

I have tried to use an Angular 2 date picker component, but they made my huge forms pretty slow, so i would like to do it without custom date pickers or any jQuery dependent widgets.

Thanks in advance.

解决方案

One way to do such a thing would be to create a component for your input that implements ControlValueAccessor

A bridge between a control and a native element.

A ControlValueAccessor abstracts the operations of writing a new value to a DOM element representing an input control.

Please see DefaultValueAccessor for more information.

Something like this should do the trick (not tested):

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;
    }
}

then you should be able to use it like this:

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

or

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

这篇关于FormControl输入中的Angular 2日期管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆