我有一个要求,用户可以在日期选择器中选择多个日期,但在每次日期选择后,mat-datepicker关闭,我想防止mat-datepicker在日期选择时关闭,并在日期选择器或日历图标之外单击时关闭日期选择器。

我在mat-datepicker上尝试了closed事件,但日期选择器在每个日期选择上都闪烁,而且当我们在日期选择器之外单击时,它不会关闭。
这是我尝试过的:
html代码:
<input formControlName="fromDate" matInput [matDatepicker]="fromDatePicker" placeholder="From Date" [min]="minDate" readonly>
<mat-datepicker-toggle matSuffix [for]="fromDatePicker"></mat-datepicker-toggle>
<mat-datepicker #fromDatePicker (closed)="_openCalendar(fromDatePicker)"></mat-datepicker>打字代码:
_openCalendar(picker: MatDatepicker<Date>) {
picker.open();
}发布于 2020-01-31 22:53:19
我阻止覆盖关闭的方法是更改MatCalendar._userSelected方法。
如果您查看MatDatePickerContent的模板,您会注意到当_userSelection发出时的调用。调用是为了关闭覆盖:(_userSelection)="datepicker.close()"。现在,在MatCalendar._userSelected.中发出_userSelection
datepicker.js,行1687,"@angular/material":"8.2.3":
_userSelected() {
this._userSelection.emit();
}因为我不希望应用程序中的所有DatePicker实例都有这种行为,所以在我的组件中,我执行了以下操作:
@ViewChild('picker', { static: true })
private picker: MatDatepicker<Date>;
private preventCloseOnSelection = true;
private readonly initCalendarUserSelected: () => void;
public model: Array<Date>;
constructor(private readonly cdr: ChangeDetectorRef) {
this.initCalendarUserSelected = MatCalendar.prototype._userSelected;
}
public ngAfterViewInit() {
this.picker.calendarHeaderComponent = CalendarTimeHeaderComponent;
this.picker.openedStream
.pipe(takeUntil(this.isUnsubscribing))
.subscribe(() => {
if (this.preventCloseOnSelection) {
MatCalendar.prototype._userSelected = () => {};
} else {
MatCalendar.prototype._userSelected = this.initCalendarUserSelected;
}
this.cdr.detectChanges();
});
}
public ngOnDestroy() {
MatCalendar.prototype._userSelected = this.initCalendarUserSelected;
}如果您希望日期选择器的所有实例都具有此行为,您可以覆盖AppComponent中某处的MatCalendar._userSelected方法,而不必费心恢复它。
另一种方法是在日期更改后执行this.picker.close = () => { };,但您必须恢复它才能始终关闭覆盖。
您可以使用matDatepickerInput的dateChange事件获取所选日期,并创建一个包含多个值的日期的数组,并且可以使用matDatepicker的dateClass输入在视图中选择这些值。
查看:
<input [(ngModel)]="model" matInput [matDatepicker]="picker" placeholder="Choose a date" (dateChange)="dateChanged($event)" />
<mat-datepicker-toggle matPrefix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker [dateClass]="dateClass"></mat-datepicker>方法:
public dateClass = (date: Date) => {
if (this.model.map((m) => +m).indexOf(+date) !== -1) {
return [ 'selected' ];
}
return [ ];
}
public dateChanged(event: MatDatepickerInputEvent<Date>) {
if (event.value) {
const date = event.value;
const index = this.model.map((m) => +m).indexOf(+date);
if (index === -1) {
this.model.push(date);
} else {
this.model.splice(index, 1)
}
}
}发布于 2021-01-10 23:05:57
在日期范围选择器的情况下,我解决了这个问题,如下所示:
export class MatDatetimeComponent {
@ViewChild(MatDateRangePicker) containerElRef;
constructor(
private resolver: ComponentFactoryResolver,
private cdr: ChangeDetectorRef,
private cdkConnectedOverlay: OverlayOutsideClickDispatcher
) {}
// store prototype close object
private selfClose: () => void;
ngAfterViewInit() {
this.selfClose = this.containerElRef.close;
}
public onOpen() {
// rewrite autoclose after date is chosen
this.containerElRef.close = () => {};
// close calendar manually on outside click
this.cdkConnectedOverlay._attachedOverlays[0]._outsidePointerEvents.subscribe(() => {
// restore saved close method
this.containerElRef.close = this.selfClose;
this.containerElRef.close();
});
}
}发布于 2021-05-17 20:41:11
因为其他解决方案对我不起作用,所以我这样做:
Typescript代码:
@ViewChild(MatDatepicker) datePicker: MatDatepicker<Date>;
constructor(
private changeDetectorRef: ChangeDetectorRef,
private cdkConnectedOverlay: OverlayOutsideClickDispatcher) { }
// store prototype close object
private selfClose: () => void;
opened() {
if (isNullOrUndefined(this.selfClose)) {
this.selfClose = this.datePicker.close;
}
// rewrite autoclose after date is chosen
this.datePicker.close = () => {};
// close calendar manually on outside click
this.cdkConnectedOverlay._attachedOverlays[0]._outsidePointerEvents.subscribe(() => {
// restore saved close method
this.datePicker.close = this.selfClose;
this.selfClose = undefined;
this.datePicker.close();
});
}模式代码:
<mat-datepicker #picker
(opened)="opened()"
></mat-datepicker>也许这对外面的人有帮助。
https://stackoverflow.com/questions/59086125
复制相似问题