#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/api5. @Kirubel нет, это не так. входные данные внутри него имеют.