【问题标题】:How to add close button to customized mat-datepicker-header如何将关闭按钮添加到自定义 mat-datepicker-header
【发布时间】:2019-12-17 17:24:36
【问题描述】:

我正在使用来自 Angular 材质的这个 UI 组件。

https://material.angular.io/components/datepicker/overview#customizing-the-calendar-header

我想在自定义标题中添加关闭按钮,但似乎还不可能。

至少我想从日期选择器标题组件中获取输出事件。

【问题讨论】:

  • 嗯...你不能添加关闭按钮是什么意思..?按钮不起作用?还是按钮根本不显示

标签: angular angular-material mat-datepicker


【解决方案1】:

由于MatDatepickerMatCalendarHeader 是两个独立的组件,您需要使用EventEmitterBehaviourSubject 通过使用服务在组件之间传递数据。

对于这个例子,我将使用一个服务。首先,您可以创建一个名为calendar-service.ts 的服务,用于在组件之间共享数据。在这个类中,我们将使用BehaviourSubject 发出更新后的布尔值,它表示日期选择器应该打开还是关闭。

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class CalendarService {

  closeCalendarSource = new BehaviorSubject<boolean>(false);
  isCloseCalander = this.closeCalendarSource.asObservable();

  constructor() { }

  closeCalander(message: boolean) {
    this.closeCalendarSource.next(message)
  }

}

MatCalendarHeader 的模板上,您应该添加一个绑定到单击事件的按钮,这将触发关闭日期选择器的操作

<button mat-icon-button (click)="closeCalendar()" >
  <mat-icon>close</mat-icon>
</button>

而在 header 的 component.ts 上,

constructor(
  private calendarService: CalendarService) {
}

closeCalendar() {
  this.calendarService.closeCalander(true);
}

在使用MatDatepicker 的主组件上,您将订阅从头组件发出当前值的可观察对象。

@ViewChild('picker', { static: false}) picker;
exampleHeader = ExampleHeader;

constructor(private calendarService: CalendarService) {}

ngOnInit() {
  this.calendarService.isCloseCalander.subscribe(isClose => {
    if (isClose) {
      this.picker.close();
    }
  });
}

我已经通过here创建了完整的演示。

【讨论】:

  • 好的,但是如果你想要多个自定义 MatDatePickerComponent 实例怎么办?它们将共享来自同一个 CalendarService 实例的数据。它不是范围安全的,并且可能导致严重的副作用。当然,您的示例适用于教程,在该教程中您将仅声明一次 mat-date-picker,但不适用于具有多个日期选择器的生产应用程序(例如,具有 3 个不同日期选择器的大型表格用于生日 + 配偶生日 +订阅日期)。
  • @SaadBenbouzid 我认为您可以通过提供服务组件级别来解决这个问题。 stackoverflow.com/questions/51775018/…
【解决方案2】:

我认为你应该看看这个example。您应该能够在没有calendarService 的情况下使其工作。基本上你可以在构造函数中抓住父日期选择器组件:

constructor(
    private datePicker: MatDatepicker<D>,
    private calendar: MatCalendar<D>,
    private dateAdapter: DateAdapter<D>,
    @Inject(MAT_DATE_FORMATS) private dateFormats: MatDateFormats,
    cdr: ChangeDetectorRef,
  ) {
    this.calendar.stateChanges.pipe(takeUntil(this.onDestroy$)).subscribe(() => cdr.markForCheck());
  }

我将它与 HTML 中的今天按钮一起使用:

<button
    mat-icon-button
    class="todayButton"
    (click)="todayClicked()"
    matTooltip="Select today"
  >
    {{ today }}
  </button>

然后调用该方法,this.datePicker.close()将关闭日历弹出:

todayClicked() {
    this.calendar.activeDate = this.dateAdapter.today();
    this.calendar._dateSelected(this.calendar.activeDate);
    this.datePicker.select(this.dateAdapter.today());
    this.datePicker.close();
  }

感谢原作者:@tabuckner

【讨论】:

  • 文档后面的唯一答案 - 但这样一个荒谬的解决方案 - +1 无论如何这不是你的错;)
【解决方案3】:

偶然发现了这个,并认为我会分享我的发现。

根据github issue,添加了一个 fork,以便您可以将组件用作包装器,因此,您将获得组件的所有简洁功能。

要利用这个,你的模板很简单

<mat-calendar-header>
  <button>TODAY</button>
</mat-calendar-header>

这里是我的 stackblitz 的链接,带有示例:https://stackblitz.com/edit/mat-datepicker-today-button?file=src/main.ts

【讨论】:

    猜你喜欢
    • 2022-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多