Пользовательский валидатор Angular 6 для сравнения текущей даты с выбранной датой не проверяется должным образом и позволяет добавить любое значение

Мне нужно проверить дату контроля над рождаемостью реактивной формы, поэтому, если пользователь выбрал значение из будущего, чтобы отключить кнопку сохранения:

import { AbstractControl } from '@angular/forms';

export function validateDOB(control: AbstractControl)
{

    let currentDateTime = new Date();
    let monthValue = currentDateTime.getMonth()+1;
    let formattedDate = currentDateTime.getFullYear() +'-'+ monthValue +'-'+currentDateTime.getDay();

    let controlValue = control.value;
    let monthOfControlValue = controlValue.getMonth()+1;
    let FinalControlValue = controlValue.getFullYear()+'-'+monthOfControlValue+'-'+controlValue.getDay;
    console.log(FinalControlValue)
    if(formattedDate<control.value)
    {
        return {response: true};
    }
    return null;
}

Объяснение:

Я работаю с инструментом выбора даты углового материала, поэтому дата будет отображаться следующим образом:

Пн, 01 октября 2018 г., 00:00:00 GMT+0300 (восточноевропейское летнее время)

первые 3 строки получают текущую дату и преобразуют ее в формат YYYY-mm-dd:

let currentDateTime = new Date();
let monthValue = currentDateTime.getMonth()+1;
let formattedDate = currentDateTime.getFullYear() +'-'+ 
              monthValue +'-'+currentDateTime.getDay();

Последние 3 строки преобразуют дату, выбранную пользователем:

let monthOfControlValue = controlValue.getMonth()+1;
let FinalControlValue = controlValue.getFullYear()+'-'+monthOfControlValue+'-'+controlValue.getDay;
console.log(FinalControlValue )

На стороне пользователя любая дата, меньше или больше, проверка не будет работать.

Я пытался провести сравнение без преобразования в YYYY-mm-dd, но это не сработало/не сработает.

Я изменил сценарий, изменив значение элемента управления на новую дату:

let controlValue = new Date(control.value);

А скрипт теперь такой:

import { AbstractControl } from '@angular/forms';

export function validateDOB(control: AbstractControl)
{

    let currentDateTime = new Date();
    let monthValue = currentDateTime.getMonth()+1;
    let formattedDate = currentDateTime.getFullYear() +'-'+ monthValue +'-'+currentDateTime.getDay();
    console.log(formattedDate)
    let controlValue = new Date(control.value);
    let monthOfControlValue = controlValue.getMonth()+1;
    let FinalControlValue = controlValue.getFullYear()+'-'+monthOfControlValue+'-'+controlValue.getDay();
    console.log(FinalControlValue)
    if(formattedDate<control.value)
    {
        return {response: true};
    }
    return null;
}

И до сих пор не работает.


person alim1990    schedule 01.10.2018    source источник
comment
Вы пытались отформатировать свои даты с помощью средства форматирования, такого как DatePipe ?   -  person veben    schedule 01.10.2018
comment
Как использовать внутреннюю функцию машинописного текста   -  person alim1990    schedule 01.10.2018
comment
Вы должны импортировать его, сконструировать, а затем использовать такой метод преобразования dateTransformed = this.datePipe.transform(date, 'yyyy-MM-dd');   -  person veben    schedule 01.10.2018
comment
могу ли я построить его внутри экспортируемой функции?   -  person alim1990    schedule 01.10.2018
comment
Да, в конструкторе   -  person veben    schedule 01.10.2018
comment
Экспортируемая функция может иметь конструктор? @вебен   -  person alim1990    schedule 01.10.2018
comment
@droidnation, почему вы позволяете пользователю выбирать будущую дату?   -  person Prashant Pimpale    schedule 02.10.2018
comment
Я не могу управлять средством выбора даты углового материала для отображения прошлых дат. Я искал его, но не смог найти никакой помощи. В любом случае @PrashantPimpale Я ответил на свой вопрос, пожалуйста, проверьте его. Меня устраивает.   -  person alim1990    schedule 02.10.2018
comment
Хорошо, но вы можете легко отключить сегодняшнюю дату и будущие даты в DatePicker, чтобы часть написания явного кода была устранена.   -  person Prashant Pimpale    schedule 02.10.2018
comment
Если вы не можете сделать то же самое, дайте мне знать   -  person Prashant Pimpale    schedule 02.10.2018
comment
Да я не умею это делать. Можете ли вы сказать мне, как это сделать, @PrashantPimpale?   -  person alim1990    schedule 02.10.2018
comment
html код пожалуйста   -  person Prashant Pimpale    schedule 02.10.2018
comment
Вот stackblitz: stackblitz.com/edit/angular-ftem5m   -  person Prashant Pimpale    schedule 02.10.2018
comment
Опубликуйте это как ответ, пожалуйста, чтобы я мог проголосовать за него.   -  person alim1990    schedule 02.10.2018


Ответы (3)


Вместо того, чтобы писать пользовательскую функцию проверки для отключения дат, я бы использовал свойство MAX средства выбора даты, чтобы отключить выбор дат «Сегодняшняя дата» и «Будущие даты».

HTML-код:

<mat-form-field class="example-full-width">
  <input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="picker" placeholder="Choose a date">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

И в файле TS:

 minDate = new Date(1900, 0, 1);
 maxDate =  new Date(new Date().setDate(new Date().getDate()-1))

Вот Пример StackBlitz

Справочная ссылка

person Prashant Pimpale    schedule 02.10.2018

не могли бы вы попробовать это?

if(currentDateTime <controlValue )

с

let controlValue = new Date(control.value);

formattedDate в данном случае является строкой.

person lesiano    schedule 01.10.2018

Часть ответа основана на помощи, предоставленной @lesiano. Но главная проблема заключалась в том, что сравнение идет с учетом времени. И, как упоминалось в этом старом ответ на переполнение стека, нам нужно установить время даты в 0's, чтобы сравнение имело место:

date1.setHours(0,0,0,0)

Рабочий пользовательский валидатор:

import { AbstractControl } from '@angular/forms';

export function validateDOB(control: AbstractControl)
{

    let currentDateTime = new Date();
    currentDateTime.setHours(0,0,0,0);

    let controlValue = new Date(control.value);
    controlValue.setHours(0,0,0,0);

    //console.log(currentDateTime+'-'+controlValue)

    if(currentDateTime<control.value)
    {
        return {response: true};
    }
    return null;
}
person alim1990    schedule 02.10.2018