Указатель даты углового материала получает значение при изменении

#angular #angular-material

#угловой #angular-material

Вопрос:

У меня есть DatePickerRange углового материала, и я хочу запустить функцию при изменении значения в DatePicker Я пробовал с функцией (изменить), но это не сработало, я был бы рад вашей помощи, как это сделать. Спасибо!

Это мой html:

 <mat-form-field class="form-field">
    <mat-label>Enter a date range</mat-label>
    <mat-date-range-input [formGroup]="range" [rangePicker]="picker">
        <input matStartDate formControlName="start" placeholder="Start date">
        <input matEndDate formControlName="end" placeholder="End date">
    </mat-date-range-input>
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-date-range-picker #picker></mat-date-range-picker>

    <mat-error *ngIf="range.controls.start.hasError('matStartDateInvalid')">Invalid start date
    </mat-error>
    <mat-error *ngIf="range.controls.end.hasError('matEndDateInvalid')">Invalid end date

    </mat-error>
    </mat-form-field>
  

И это функция, которую я хочу активировать:

    @Output() newItemEvent = new EventEmitter<bookedDate>();
      addNewDate() {
        this.dateRange.dateStart = this.range.get('start').value;
        this.dateRange.dateEnd = this.range.get('end').value;
        this.newItemEvent.emit(this.dateRange);
      }
  

Ответ №1:

Мой подход заключался в добавлении переменных ссылки на шаблон к входным данным для matStartDate и matEndDate . Это dateRangeStart и dateRangeEnd в примере шаблона ниже:

 // Template

<mat-form-field appearance="standard">
  <mat-label>{{reportField.value.label}}</mat-label>
  <mat-date-range-input [rangePicker]="dateRangePicker">
    <input matStartDate
      placeholder="Start date"
      #dateRangeStart>
    <input matEndDate
      placeholder="End date"
      #dateRangeEnd
      (dateChange)="dateRangeChange(dateRangeStart, dateRangeEnd)">
  </mat-date-range-input>
  <mat-datepicker-toggle matPrefix
    [for]="dateRangePicker">
  </mat-datepicker-toggle>
  <mat-date-range-picker #dateRangePicker></mat-date-range-picker>
</mat-form-field>
  

Затем значения этих входных данных могут быть доступны с помощью функции, вызываемой dateChange выходом на matEndDate .

 // Component

dateRangeChange(dateRangeStart: HTMLInputElement, dateRangeEnd: HTMLInputElement) {
  console.log(dateRangeStart.value);
  console.log(dateRangeEnd.value);
}
  

Это позволяет избежать необходимости в dateChange событии на обоих входах.

Комментарии:

1. Это сработало так, как я хочу, чтобы это работало … Слава!

2. Обратите внимание, что это работает только при использовании средства выбора. Если значение изменяется в тексте, то функция не будет запущена

Ответ №2:

у меня есть что-то похожее на вашу проблему, это работает для меня, поэтому я надеюсь, что это поможет вам или даст подсказку о решении вот мой html :

 <mat-form-field class="dialogform">
  <mat-label>Duree du Session : </mat-label>
    <input matInput
       required
       placeholder=""
       [satDatepicker]="picker"
       [value]="dateRangeDisp"
       (dateChange)="saveDate($event)"
    >
  <sat-datepicker #picker [rangeMode]="true"></sat-datepicker>
  <sat-datepicker-toggle matSuffix [for]="picker"></sat-datepicker-toggle>
  </mat-form-field>
  

и функция :

      saveDate(event: any) {
    // look at how the date is emitted from save
    console.log(event.target.value.begin);
    //this.session.dateDebut = event.target.value.begin;
    console.log(event.target.value.end);

    // change in view
     this.dateRangeDisp = event.target.value;


    // save date range as string value for sending to db

    // ... save to db
  }
  

Комментарии:

1. забыл это объявление: satDatePicker: { begin: Date; end: Date; }; dateRangeDisp: любой;

2. У меня не работает, он вообще не входит в мою функцию AddNewDate. в любом случае спасибо.

3. это может быть базовым, но нажмите F12 и посмотрите, в чем ошибка, если ее нет, это означает, что она даже не достигает вашей функции и удачи

4. Я четко проверил… но я не вижу никакой проблемы.

Ответ №3:

Я сам столкнулся с этой проблемой, вот решение, которое мне помогло: component.ts:

     import * as moment from 'moment';
    import { FormControl, FormGroup } from "@angular/forms";
    import { DateAdapter, MAT_DATE_FORMATS,  MatDateFormats } from "@angular/material/core";
    import {  MomentDateAdapter } from '@angular/material-moment-adapter';
        const CUSTOM_DATE_FORMATS: MatDateFormats = {
        parse: {
            dateInput: 'D/MM/YYYY'
        },
        display: {
            dateInput: 'DD/MM/YYYY',
            monthYearLabel: 'MMMM Y',
            dateA11yLabel: 'LL',
            monthYearA11yLabel: 'MMMM Y'
        }
    };
    @Component({
        providers: [
            {provide: MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS},
            {provide: DateAdapter, useClass: MomentDateAdapter}
        ],
    })
    
        @ViewChild('picker') picker: any;
        dateRange: moment.Moment;
        disabled = false;
        tempDate = new Date().setMonth(new Date().getMonth() - 1);
        range = new FormGroup({
            start: new FormControl(new Date(this.tempDate)),
            end: new FormControl(new Date()),
        });
    
        ngAfterViewInit() {
            this.range.valueChanges.pipe(
                debounceTime(200)
            ).subscribe(event => {
                if (event.start amp;amp; event.end) {
                    this.onDateChanged(event);
                }
            });
        }  
   
    <mat-form-field class="date-range" appearance="fill">
    <mat-label>Enter a date range</mat-label>
    <mat-date-range-input
    [formGroup]="range"
    [rangePicker]="picker">
    <input matStartDate formControlName="start" placeholder="Start date">
    <input matEndDate formControlName="end" placeholder="End date">
    </mat-date-range-input>
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-date-range-picker #picker></mat-date-range-picker>
    <mat-error *ngIf="range.controls.start.hasError('matStartDateInvalid')">Invalid start date</mat-error>
    <mat-error *ngIf="range.controls.end.hasError('matEndDateInvalid')">Invalid end date</mat-error>
    </mat-form-field>  

Комментарии:

1. Описание вашего кода помогло бы людям понять решение. Пожалуйста, отредактируйте ответ с объяснением.

2. Отмена — это единственный, казалось бы, простой способ вызвать достаточную задержку для сброса ввода календаря в случае, когда вы выбираете более раннюю дату, это лучшее решение

3. Это неверно, потому что конечная дата будет объектом moment в самой форме, а не собственной JS date(). Это вы не можете переопределить, и вам придется взломать, чтобы проверить, является ли это моментом или собственной датой JS, если вы хотите манипулировать значениями.

Ответ №4:

@Kirubel и @Irad Amri спасибо!

В конечном итоге это работает для меня таким образом:

HTML-

 <mat-form-field class="form-field">
    <mat-label>Enter a date range</mat-label>
    <mat-date-range-input [formGroup]="range" [rangePicker]="picker">
        <input **(dateInput)="addEvent('input', $event)" 
(dateChange)="addEvent('change', $event)"** matStartDate
            formControlName="start" placeholder="Start date">
        <input **(dateInput)="addNewDate('input', $event)" 
 (dateChange)="addNewDate('change', $event)"** matEndDate
            formControlName="end" placeholder="End date">
    </mat-date-range-input>
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-date-range-picker #picker></mat-date-range-picker>

    <mat-error *ngIf="range.controls.start.hasError('matStartDateInvalid')">Invalid 
 start date
    </mat-error>
    <mat-error *ngIf="range.controls.end.hasError('matEndDateInvalid')">Invalid end 
 date

    </mat-error>
</mat-form-field>
  

TS-

 @Output() newItemEvent = new EventEmitter<bookedDate>();

  addNewDate(type: string, event: MatDatepickerInputEvent<Date>) {
    this.dateRange.dateStart = this.range.get('start').value;
    this.dateRange.dateEnd = this.range.get('end').value;
    this.newItemEvent.emit(this.dateRange);
  }
  

И еще раз, большое спасибо за помощь!

Ответ №5:

Я использовал (dateChange)="function()" для запуска изменения даты в mat date picker.

Ответ №6:

Хотя ответ Мэтта хороший, недостатком этого подхода является то, что (dateChange) срабатывает только при изменении ввода конечной даты. Например, если пользователь изменяет начальную дату, введя, его событие не сработает.

В итоге я использовал Subject ‘s для объединения наблюдаемых с обоих входных данных. Это позволяет мне прослушивать, когда каждый отдельный ввод был изменен. Либо с помощью средства выбора, либо путем ввода. Проверяя value , переносимое событием, мы можем определить, когда пользователь закончил выбирать обе действительные даты.

   <mat-form-field appearance="fill">
          <mat-label>Travel date</mat-label>
            <mat-date-range-input [rangePicker]="picker">
              <input matStartDate placeholder="Start date" (dateChange)="startDatePicker.next($event)">
              <input matEndDate placeholder="End date"  (dateChange)="endDatePicker.next($event)">
            </mat-date-range-input>
            <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
            <mat-date-range-picker #picker></mat-date-range-picker>
        </mat-form-field>
  

TS:

   startDatePicker = new Subject<MatDatepickerInputEvent<any>>();
  endDatePicker = new Subject<MatDatepickerInputEvent<any>>();

  ngOnInit(): void {
    const dateChange$ = combineLatest([this.startDatePicker, this.endDatePicker]).pipe(
      map(([a$, b$]) => ({
        start: a$,
        end: b$
      }))
    );

    dateChange$.subscribe((data) => {
      if (data.start.value amp;amp; data.end.value) {
        console.log('User has picked both ranges!');
      }
    });
  }
  

Ответ №7:

Попробуйте dateChange вместо этого

 <mat-date-range-input [formGroup]="range" [rangePicker]="picker" (dateChange)="addNewDate()">
    <input matStartDate formControlName="start" placeholder="Start date">
    <input matEndDate formControlName="end" placeholder="End date">
</mat-date-range-input>
  

Комментарии:

1. Как говорится в документации, «Событие (dateInput) будет срабатывать всякий раз, когда значение изменяется из-за ввода пользователем или выбора даты из календаря. Событие (dateChange) будет срабатывать всякий раз, когда пользователь заканчивает вводить ввод (при <ввод> размытие) или когда пользователь выбирает дату из календаря.» Или попробуйте (dateChange)="addNewDate($event)"

2. Можете ли вы создать пример stackblitz с минимальным количеством кода?

3. Это не будет работать прямо сейчас, поскольку у mat-date-range-input нет выходных событий

4. Как указано в Документации, mat-date-range-input имеет событие вывода @Output() dateChange: EventEmitter<MatDatepickerInputEvent<D, S>> . Вы можете обратиться сюда material.angular.io/components/datepicker/api

5. @Kirubel нет, это не так. входные данные внутри него имеют.