angular - 如何使用角材料实现范围内联日历?
问题描述
我想使用材料日历作为范围内联日历来显示和插入日期范围。使用 mat-date-range-picker 时,这只是工作(但不是内联)。使用 mat-calendar 时,它适用于内联,但不适用于远程。但是,如果我将 selectedRangeValue 作为 DateRange 而不是 Date 传递,则 Range 会正确显示。
唯一仍然缺少的是输入...
这是我现在使用的代码(缩写):
<mat-calendar (selectedChange)="selectedRangeChange($event)"
[selected]="selectedRangeValue"
>
</mat-calendar>
selectedRangeValue: DateRange<Date> = new DateRange<Date>(this.selectedValue.begin, this.selectedValue.end);
我必须这样做,因为土星日期选择器仅在 Angular 9 之前受支持,而从 Angular 10 开始,Material Datepicker 支持日期范围。但是这个“内联日期范围日历”我只是无法工作......
我发现https://github.com/angular/components/issues/20697描述了同样的问题并找到了解决方案,但没有写下来,所以没有帮助。
我也试着去了解angular material datepicker的源码,可惜还是没搞懂。我将不胜感激任何帮助或提示。
解决方案
我找到了解决这个问题的方法。虽然我不确定这是否是最好的方法,但我想提供解决方案。
我必须为内联范围日历创建一个新的角度组件:
HTML 架构
<mat-calendar
#calendar
[selected]="selectedRangeValue"
(selectedChange)="selectedChange($event)"
>
</mat-calendar>
打字稿
import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
import {
DateRange, DefaultMatCalendarRangeStrategy,
MAT_DATE_RANGE_SELECTION_STRATEGY, MatCalendar,
} from '@angular/material/datepicker';
import {isNullOrUndefined} from '../../util/is-null-or-undefined';
import moment from 'moment';
@Component({
// tslint:disable-next-line:component-selector
selector: 'inline-range-calendar',
templateUrl: './inline-range-calendar.component.html',
styleUrls: ['./inline-range-calendar.component.sass'],
providers: [{
provide: MAT_DATE_RANGE_SELECTION_STRATEGY,
useClass: DefaultMatCalendarRangeStrategy
}]
})
export class InlineRangeCalendarComponent implements OnInit {
@ViewChild(MatCalendar) calendar: MatCalendar<Date>;
@Input() selectedRangeValue: DateRange<Date>;
@Output() selectedRangeValueChange = new EventEmitter<DateRange<Date>>();
ngOnInit(): void {
}
selectedChange($event) {
const m = moment($event);
if (!isNullOrUndefined(this.selectedRangeValue.end)) {
const start = this.selectedRangeValue.start;
// @ts-ignore the parser thinks that this is a date, but it is a moment.js object, so this will work
start.set(m.toObject());
this.selectedRangeValue = new DateRange<Date>(start, undefined);
this.selectedRangeValueChange.emit(this.selectedRangeValue);
} else {
const end = (!isNullOrUndefined(this.selectedRangeValue.end)) ? this.selectedRangeValue.end : moment(m);
// @ts-ignore the parser thinks that this is a date, but it is a moment.js object, so this will work
end.set(m.toObject());
// @ts-ignore the parser thinks that this is a date, but it is a moment.js object, so this will work
this.selectedRangeValue = new DateRange<Date>(this.selectedRangeValue.start, end);
if (this.selectedRangeValue.end < this.selectedRangeValue.start) {
this.selectedRangeValue = new DateRange<Date>(this.selectedRangeValue.end, this.selectedRangeValue.start);
}
this.selectedRangeValueChange.emit(this.selectedRangeValue);
}
}
}
希望这可以帮助某人。
推荐阅读
- android - Android浏览器在浏览器未打开时推送通知
- django - 从 django rest 框架序列化程序中的数组中删除键
- javascript - 如何捕获 HTML 5 视频元素下载事件
- python - 将python中的列表分成元组
- wix - 使用 Wix 将整个目录添加到 MSI 数据库的规范方法是什么?
- docker - 码头工人。无法执行从主机复制到映像的文件
- java - 在 bitbucket api 方法中从 InputStream 中读取内容
- javascript - 你如何在javascript中通过其内部文本单击按钮?
- sql - Oracle:如何计算两个日期之间数据库中的插入次数
- sapui5 - 格式化程序传递静态值