2017-02-15 10 views
6

У меня есть динамически генерируемая Angular 2 FormGroup с несколькими полями ввода FormControl. Некоторыми входами являются Даты, которые извлекаются с сервера как временные метки unix.Угловая 2-метровая трубка внутри входа FormControl

Что я хотел бы сделать, это:

  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

Попытка изменить ввод даты, способ не будет работать, потому что труба будет постоянно пытаться преобразовать входное значение, таким образом, делая ввод непригодным, если не выбрасывает аргумент Invalid для исключения 'DatePipe'.

Чтобы уточнить, я заполняю свою форму, используя FormGroup.patchValue() api, и отправлю данные формы, используя FormGroup.getRawValue() api.

Я попытался использовать компонент для определения даты в формате Angular 2, но они сделали мои огромные формы довольно медленными, поэтому я хотел бы сделать это без специальных сортировщиков дат или любых зависимых от jQuery виджетов.

Заранее спасибо.

ответ

7

Один из способов сделать такую ​​вещь было бы создать компонент для вашего входа, который реализует ControlValueAccessor

моста между управлением и родной стихии.

A 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> 
+0

Спасибо, я попробую этот подход и вернусь к вам как можно скорее. – ktsangop

+0

К сожалению, я просто понял, что забыл важную роль в декларации '@ Component'. Я отредактирую как можно скорее. – n00dl3

+0

changeCallback и touchCallback необходимо инициализировать, я полагаю, что это 'touchCallback: any =() => {};' Кроме этого, и после большого чтения я думаю, что понимаю, как это работает сейчас! Примите ваш ответ в ближайшее время, если у меня нет других вопросов. Спасибо! – ktsangop