问题
I would like to catch the event that comes from the month "left" and "right" selection buttons, but I couldn't find any documentation about it.
What events are fired when the "left" and "right" month selection boxes are clicked in the Material Datepicker?
回答1:
Well, my another response is wrong, Let's go to take another aproach. Imagine we has a CustomTemplate Header. As we want that it's looks like the original DatePicker header we are copy the template of this that is in gitHub of angular, but we are change the functions in button next an prev, so it's like
<div class="mat-calendar-header">
<div class="mat-calendar-controls">
<button mat-button type="button" class="mat-calendar-period-button"
(click)="currentPeriodClicked()" [attr.aria-label]="periodButtonLabel"
cdkAriaLive="polite">
{{periodButtonText}}
<div class="mat-calendar-arrow"
[class.mat-calendar-invert]="calendar.currentView != 'month'"></div>
</button>
<div class="mat-calendar-spacer"></div>
<ng-content></ng-content>
<!--see that we change previousClicked by customPrev-->
<button mat-icon-button type="button" class="mat-calendar-previous-button"
[disabled]="!previousEnabled()" (click)="customPrev()"
[attr.aria-label]="prevButtonLabel">
</button>
<!--see that we change nextClicked by customNext-->
<button mat-icon-button type="button" class="mat-calendar-next-button"
[disabled]="!nextEnabled()" (click)="customNext()"
[attr.aria-label]="nextButtonLabel">
</button>
</div>
</div>
Now we defined our customHeader extends from MatCalendarHeader
export class ExampleHeader extends MatCalendarHeader<any> {
/** Handles user clicks on the period label. */
currentPeriodClicked(): void {
this.calendar.currentView = this.calendar.currentView == 'month' ? 'multi-year' : 'month';
}
/** Handles user clicks on the previous button. */
customPrev(): void {
console.log(this.calendar.activeDate)
this.previousClicked()
}
/** Handles user clicks on the next button. */
customNext(): void {
console.log(this.calendar.activeDate)
this.nextClicked()
}
Then , just only say that use this ExampleHeader
<mat-form-field>
<mat-label>Custom calendar header</mat-label>
<input matInput [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker [calendarHeaderComponent]="exampleHeader"></mat-datepicker>
</mat-form-field>
See in stackblitz
回答2:
the only way I've found is, (idea from onthecode) in open, check for querySelectorAll of the buttons. some like
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker (opened)="openCalendar()">
</mat-datepicker>
</mat-form-field>
constructor(private renderer: Renderer2) { }
openCalendar() {
setTimeout(() => {
const buttons = document.querySelectorAll
('.mat-calendar-previous-button,.mat-calendar-next-button')
if (buttons) {
Array.from(buttons).forEach(button => {
this.renderer.listen(button, "click", (event) => {
console.log('Arrow button clicked')
});
})
}
})
}
see stackblitz
回答3:
on the Template where:
<mat-datepicker #picker (opened)="initEvents()"></mat-datepicker>
add an event listener when the datepicker is open and add to the buttons the click event...
TS:
initEvents(): void {
setTimeout(() => {
const prev = document.querySelector('.mat-calendar-previous-button');
const next = document.querySelector('.mat-calendar-next-button');
prev.addEventListener('click', () => { // Previous Button
console.log('Prev');
});
next.addEventListener('click', () => { // Next Button
console.log('Prev');
});
}, 150);
}
Hope it works :)
without the small delay, it will display u a null reference, anyway with the small delay it should work well, in any way there's a delay when the user clicks on that datepicker by the animation so..
btw: it displays null because the event occurs before the element (our buttons) are in the DOM...
EDIT: one more thing am this solution may not the best because ur register events every time the datepicker is opened, but its the best and the fastest way which i found, an a better way of doing that is by creating a custom header... but its a lot of codes to write.., u can check it on official docs if u want.
来源:https://stackoverflow.com/questions/57510066/how-can-i-catch-the-material-datepicker-month-pagination-event