FormControl输入中的Angular 2日期管道

时间:2017-02-15 15:53:30

标签: forms angular datepicker pipe

我有一个动态生成的Angular 2 FormGroup,其中包含多个FormControl输入字段。一些输入是日期,它们作为unix时间戳从服务器获取。

我想做的是:

  1. 能够将unix时间戳转换为人类可读的形式, 何时填充我的FormGroup,以及
  2. 翻译人类 表单时unix时间戳的日期表示 提交。
  3. 第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'异常抛出Invalid参数,则输入不可用。

    为了澄清,我使用FormGroup.patchValue() api填写表单,并使用FormGroup.getRawValue() api提交表单数据。

    我曾尝试使用Angular 2日期选择器组件,但它们使我的巨大表单非常慢,所以我想在没有自定义日期选择器或任何jQuery依赖小部件的情况下进行此操作。

    提前致谢。

1 个答案:

答案 0 :(得分:9)

执行此类操作的一种方法是为您的输入创建一个实现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>