Угловая труба с двумя датами внутри входа FormControl
У меня есть динамически генерируемая Angular 2 FormGroup с несколькими полями ввода FormControl. Некоторые из входных данных являются датами, которые выбираются с сервера как метки времени Unix.
Что я хотел бы сделать, это:
- чтобы иметь возможность переводить метку времени Unix в удобочитаемую форму, когда моя FormGroup заполнена, а также
- перевести человеческое представление даты в метку времени 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()
апи.
Я пытался использовать компонент выбора даты в Angular 2, но они делали мои огромные формы довольно медленными, поэтому я хотел бы сделать это без пользовательских средств выбора даты или каких-либо зависимых от jQuery виджетов.
Заранее спасибо.
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>