【问题标题】:Angular 2 date pipe inside a FormControl inputFormControl 输入内的 Angular 2 日期管道
【发布时间】:2017-07-04 09:23:21
【问题描述】:

我有一个动态生成的带有多个 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 相关小部件的情况下这样做。

提前致谢。

【问题讨论】:

    标签: forms angular datepicker pipe


    【解决方案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>
    

    【讨论】:

    • 谢谢,我会尝试这种方法,并尽快回复您。
    • 糟糕,我刚刚意识到我忘记了@Component 声明中的一个重要部分。我会尽快编辑。
    • changeCallback 和 touchCallback 需要初始化我想像这样touchCallback : any = () =&gt; {}; 除此之外,经过大量阅读,我想我现在明白它是如何工作的了!如果我没有其他问题,将很快接受您的回答。谢谢!
    • 你说得对,它们需要初始化,我编辑了。
    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 2023-03-15
    相关资源
    最近更新 更多