繁体   English   中英

如何捕捉 Material Datepicker 月份分页事件?

[英]How can I catch the Material Datepicker month pagination event?

我想捕捉来自月份“左”和“右”选择按钮的事件,但我找不到任何关于它的文档。

材料日期选择器月份选择器图像

在 Material Datepicker 中单击“左”和“右”月份选择框时会触发哪些事件?

好吧,我的另一个回答是错误的,让我们换一个方法。 假设我们有一个 CustomTemplate Header。 因为我们希望它看起来像原始的 DatePicker 标头,所以我们复制了angular 的 gitHub 中的模板,但是我们更改了上一个按钮旁边的功能,所以就像

<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>  

现在我们定义了从 MatCalendarHeader 扩展的 customHeader

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()
  }

然后,只说使用这个 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>

堆栈闪电战中查看

还有一个解决方法是使用 dateClass

@ViewChild('picker',{static:false}) calendar: MatDatepicker<any>;
  setClass() {
    return (date: any) => {
      if (date.getDate() == 1) this.changeMonth(
         {month:date.getMonth()+1,
          year:date.getFullYear()
          });
    };
  }

  changeMonth(date)
  {
    console.log(date)
  }

你在哪里

 <mat-form-field>
  <mat-label>Choose a date</mat-label>
  <input matInput [matDatepicker]="picker">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker [dateClass]="setClass()"></mat-datepicker>
</mat-form-field>

堆栈闪电战

好吧,如果没有充分的理由,没有人有兴趣知道月份何时更改。 典型的原因是调用一个 API,该 API 返回一个包含“特殊”天数并显示在日历中的数组。

要改变这个特殊日子的方面,我们可以认为我们可以使用自己的函数 dateClass 但请记住,我们正在寻找函数执行后的天数 (*)。 所以我们需要使用Renderer2来添加类。

如果我们收到的数据有点像(见“day”是一个字符串)

  [
    {day:'2020-02-06',data:'one'},
    {day:'2020-02-16',data:'two'},
    {day:'2020-02-22',data:'three'}
  ]

我们的函数 changeMonth 变成了这样:

changeMonth(date) {
    this.dataService.getData(date.month, date.year).subscribe(res => {
      setTimeout(() => {
        let elements = document.querySelectorAll(".calendar");
        if (elements && elements.length) {
          const cells = elements[0].querySelectorAll(".mat-calendar-body-cell");
          cells.forEach(x => {
            const date = new Date(x.getAttribute("aria-label"));
            const dateTxt =
              date.getFullYear() +
              "-" +
              ("00" + (date.getMonth() + 1)).slice(-2) +
              "-" +
              ("00" + date.getDate()).slice(-2);

            if (res.find(x => x.day == dateTxt))
            {
              this.renderer.addClass(x, "special");
            }
          });
        }
      });
    });
  }

(*) 我们也可以在 ngOnInit 中询问“特殊日子”,然后简单地使用 dateClass 函数

我发现的唯一方法是,(来自onthecode 的想法)打开,检查 querySelectorAll 的按钮。 有些喜欢

<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')
          });
        })
      }
    })
  }

堆栈闪电战

在您的 component.ts 中收听落在您的 mat-calendar 下一个/上一个按钮上的点击事件。 mat-calendar 按钮的唯一标识符可能是 ariaLabel。

 @HostListener('click', ['$event']) onClick(event: any) { // get the clicked element if (event.target.ariaLabel && event.target.ariaLabel.includes("Previous month")) { console.log('previous'); } else if (event.target.ariaLabel && event.target.ariaLabel.includes("Next month")) { console.log('next'); } }

在模板上:

<mat-datepicker #picker (opened)="initEvents()"></mat-datepicker>

当日期选择器打开时添加一个事件侦听器并将单击事件添加到按钮...

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);

}

希望它有效:)

如果没有小延迟,它将显示 ua null 引用,无论如何,小延迟它应该可以正常工作,无论如何,当用户通过动画单击该日期选择器时会出现延迟。

顺便说一句:它显示 null 因为该事件发生在元素(我们的按钮)在 DOM 中之前......

编辑:这个解决方案的另一件事可能不是最好的,因为每次打开日期选择器时都会注册事件,但它是我发现的最好和最快的方法,更好的方法是创建自定义标题.. . 但它有很多代码要写..,如果你愿意,你可以在官方文档上查看它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM