Подтвердить что ты не робот

Ошибка формата при использовании пользовательского объекта ControlValueAccessor для типа ввода = даты в Angular2 rc4

Прежде чем начать, я использую Angular2 rc4 с typescript. В случае, если вам интересно, я пока не могу обновить, поэтому мне нужно сделать эту работу в рамках ограничений rc4. Кроме того, я ng2 noob, так что все еще получаю голову от концепций и всех изменений между "кандидатами на выпуск".

Проведя довольно много исследований в области доступа к ценностям, я решил создать его специально для <input type=date />, чтобы избежать необходимости использования отдельного свойства mule в компоненте, чтобы превратить дату в строку для ввода.

Я нашел этот смысл, который, казалось, делал многое, что я хотел сделать.

Используя это как начальную и почти конечную точку, я придумал следующее:

import { Directive, ElementRef, Renderer, forwardRef } from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
import { isBlank, isDate } from "@angular/forms/src/facade/lang";
import moment from "moment";

export const DATE_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => DateValueAccessor),
    multi: true
};

@Directive({
    selector:
    "input[type=date][formControlName],input[type=date][formControl],input[type=date][ngModel]",
    host: {
        "(change)": "onChange($event.target.value)",
        "(input)": "onChange($event.target.value)",
        "(blur)": "onTouched()"
    },
    providers: [DATE_VALUE_ACCESSOR]
})
export class DateValueAccessor implements ControlValueAccessor {
    onChange = (_: any) => {
        // we don't need to do anything here
    };

    onTouched = () => {
        // we don't need to do anything here
    };

    constructor(
        private _renderer: Renderer,
        private _elementRef: ElementRef) {
    }

    writeValue(value: any): void {
        var normalizedValue: string = isBlank(value) ? "" : (isDate(value) ? moment(value).format("YYYY-MM-DD") : "");
        this._renderer.setElementProperty(this._elementRef.nativeElement, "value", normalizedValue);
    }

    registerOnChange(fn: (_: any) => void): void {
        this.onChange = (value: string) => {
            var date: moment.Moment = moment(value, "YYYY-MM-DD");
            var newValue: Date = date.isValid() ? date.toDate() : undefined;
            fn(newValue);
        };
    }

    registerOnTouched(fn: () => void): void {
        this.onTouched = fn;
    }
}

Я чувствую, что я почти там, но не совсем!

update. Когда форма загружается первой, все очень грустно, но когда я пытаюсь выбрать новую дату, браузер жалуется на формат. /обновление

Ошибка, которую я вижу в моем devtools:

Указанное значение "Пт. 09.09.2016 00:00:00 GMT + 0100 (GMT Summer Time)" не соответствует требуемому формату "yyyy-MM-dd".

Я сжег немного времени, настраивая код и перемещая вещи. Я также попытался сделать вызов writeValue изнутри onChange (как видно из этого plnkr), но я все еще видел ошибку..

Кто-нибудь это сделал? Есть ли что-то очевидное в моем коде, который я пропустил?

4b9b3361

Ответ 1

Следует использовать более современную версию Angular (2.1.0), но изменения должны применяться, и вы можете видеть, что модель правильно привязывается к вашей форматированной строке, здесь Plunker: https://plnkr.co/edit/8U0o0m49646tMH0kr1Mx?p=preview

Единственное изменение вашего кода:

registerOnChange(fn: (_: any) => void): void {
    this.onChange = fn;
}

Это не означает, что текст на дисплее меняется, поскольку это, насколько мне известно, привязано к типу ввода = "дата" как элемент и не может быть переопределено. Быстрый поиск приведет меня к Есть ли способ изменить тип ввода = "date" формат?, который, похоже, подтверждает это утверждение.