- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的 Angular 应用程序中,我需要从 momentjs 进行交换至dayjs .
因为我用的是material我必须更换 moment-date-adapter
使用 dayjs-date-adapter,所以我编写了自己的日期适配器,但我不明白 momentjs 如何解析像 12122020
这样的日期没有任何分隔符(您可以在操作中看到它 here )。
我尝试通过设置 MatDateFormats
来实现它,带有一个日期输入数组。
但我不知道这是否是最好的解决方案,因为我在 moment-date-adapter 中看不到它
MatDateFormats = {
parse: {
dateInput: ['D/M/YYYY', 'DMYYYY'],
},
display: {
dateInput: 'DD/MM/YYYY',
monthYearLabel: 'MMMM YYYY',
dateA11yLabel: 'DD/MM/YYYY',
monthYearA11yLabel: 'MMMM YYYY',
}
}
dayjs-date-adapter
export interface DayJsDateAdapterOptions {
/**
* Turns the use of utc dates on or off.
* Changing this will change how Angular Material components like DatePicker output dates.
* {@default false}
*/
useUtc?: boolean;
}
/** InjectionToken for Dayjs date adapter to configure options. */
export const MAT_DAYJS_DATE_ADAPTER_OPTIONS = new InjectionToken<DayJsDateAdapterOptions>(
'MAT_DAYJS_DATE_ADAPTER_OPTIONS', {
providedIn: 'root',
factory: MAT_DAYJS_DATE_ADAPTER_OPTIONS_FACTORY
});
export function MAT_DAYJS_DATE_ADAPTER_OPTIONS_FACTORY(): DayJsDateAdapterOptions {
return {
useUtc: false
};
}
/** Creates an array and fills it with values. */
function range<T>(length: number, valueFunction: (index: number) => T): T[] {
const valuesArray = Array(length);
for (let i = 0; i < length; i++) {
valuesArray[i] = valueFunction(i);
}
return valuesArray;
}
/** Adapts Dayjs Dates for use with Angular Material. */
export class DayjsDateAdapter extends DateAdapter<Dayjs> {
private localeData: {
firstDayOfWeek: number,
longMonths: string[],
shortMonths: string[],
dates: string[],
longDaysOfWeek: string[],
shortDaysOfWeek: string[],
narrowDaysOfWeek: string[]
};
constructor(@Optional() @Inject(MAT_DATE_LOCALE) public dateLocale: string,
@Optional() @Inject(MAT_DAYJS_DATE_ADAPTER_OPTIONS) private options?:
DayJsDateAdapterOptions) {
super();
this.initializeParser(dateLocale);
}
private get shouldUseUtc(): boolean {
const {useUtc}: DayJsDateAdapterOptions = this.options || {};
return !!useUtc;
}
// TODO: Implement
setLocale(locale: string) {
super.setLocale(locale);
const dayJsLocaleData = this.dayJs().localeData();
this.localeData = {
firstDayOfWeek: dayJsLocaleData.firstDayOfWeek(),
longMonths: dayJsLocaleData.months(),
shortMonths: dayJsLocaleData.monthsShort(),
dates: range(31, (i) => this.createDate(2017, 0, i + 1).format('D')),
longDaysOfWeek: range(7, (i) => this.dayJs().set('day', i).format('dddd')),
shortDaysOfWeek: dayJsLocaleData.weekdaysShort(),
narrowDaysOfWeek: dayJsLocaleData.weekdaysMin(),
};
}
getYear(date: Dayjs): number {
return this.dayJs(date).year();
}
getMonth(date: Dayjs): number {
return this.dayJs(date).month();
}
getDate(date: Dayjs): number {
return this.dayJs(date).date();
}
getDayOfWeek(date: Dayjs): number {
return this.dayJs(date).day();
}
getMonthNames(style: 'long' | 'short' | 'narrow'): string[] {
return style === 'long' ? this.localeData.longMonths : this.localeData.shortMonths;
}
getDateNames(): string[] {
return this.localeData.dates;
}
getDayOfWeekNames(style: 'long' | 'short' | 'narrow'): string[] {
if (style === 'long') {
return this.localeData.longDaysOfWeek;
}
if (style === 'short') {
return this.localeData.shortDaysOfWeek;
}
return this.localeData.narrowDaysOfWeek;
}
getYearName(date: Dayjs): string {
return this.dayJs(date).format('YYYY');
}
getFirstDayOfWeek(): number {
return this.localeData.firstDayOfWeek;
}
getNumDaysInMonth(date: Dayjs): number {
return this.dayJs(date).daysInMonth();
}
clone(date: Dayjs): Dayjs {
return date.clone();
}
createDate(year: number, month: number, date: number): Dayjs {
const returnDayjs = this.dayJs()
.set('year', year)
.set('month', month)
.set('date', date);
return returnDayjs;
}
today(): Dayjs {
return this.dayJs();
}
parse(value: any, parseFormat: string): Dayjs | null {
if (value && typeof value === 'string') {
return this.dayJs(value, parseFormat, this.locale);
}
return value ? this.dayJs(value).locale(this.locale) : null;
}
format(date: Dayjs, displayFormat: string): string {
if (!this.isValid(date)) {
throw Error('DayjsDateAdapter: Cannot format invalid date.');
}
return date.locale(this.locale).format(displayFormat);
}
addCalendarYears(date: Dayjs, years: number): Dayjs {
return date.add(years, 'year');
}
addCalendarMonths(date: Dayjs, months: number): Dayjs {
return date.add(months, 'month');
}
addCalendarDays(date: Dayjs, days: number): Dayjs {
return date.add(days, 'day');
}
toIso8601(date: Dayjs): string {
return date.toISOString();
}
deserialize(value: any): Dayjs | null {
let date;
if (value instanceof Date) {
date = this.dayJs(value);
} else if (this.isDateInstance(value)) {
// NOTE: assumes that cloning also sets the correct locale.
return this.clone(value);
}
if (typeof value === 'string') {
if (!value) {
return null;
}
date = this.dayJs(value).toISOString();
}
if (date && this.isValid(date)) {
return this.dayJs(date);
}
return super.deserialize(value);
}
isDateInstance(obj: any): boolean {
return dayjs.isDayjs(obj);
}
isValid(date: Dayjs): boolean {
return this.dayJs(date).isValid();
}
invalid(): Dayjs {
return this.dayJs(null);
}
private dayJs(input?: any, format?: string, locale?: string): Dayjs {
if (!this.shouldUseUtc) {
return dayjs(input, format, locale, false);
}
return dayjs(input, {format, locale, utc: this.shouldUseUtc}, locale, false).utc();
}
private initializeParser(dateLocale: string) {
if (this.shouldUseUtc) {
dayjs.extend(utc);
}
dayjs.extend(LocalizedFormat);
dayjs.extend(customParseFormat);
dayjs.extend(localeData);
}
}
最佳答案
您在 MatDateFormats 的 parse 属性中使用的 dateInput 用于 dayjs-date-adapter 的 parse 函数。现在您提供一个数组作为 dateInput,但您的函数需要一个字符串。 Dayjs(与 moment 不同)无法处理格式数组。如果要使用数组来支持多种格式,则必须弄清楚要在解析函数中使用哪种格式的数组。最简单的方法可能只是遍历您可能的格式并返回 dayjs 对象(如果它是有效的)。
像这样的东西(注意我没有测试过这个):
parse(value: any, parseFormats: string[]): Dayjs | null {
if (value && typeof value === 'string') {
parseFormats.forEach(parseFormat => {
const parsed = this.dayJs(value, parseFormat, this.locale);
if (parsed.isValid()) {
return parsed;
}
}
// return an invalid object if it could not be parsed with the supplied formats
return this.dayJs(null);
}
return value ? this.dayJs(value).locale(this.locale) : null;
}
请注意,在我自己的适配器中,我稍微更改了私有(private) dayJs 函数,因为在格式选项中也提供语言环境给了我一些奇怪的行为。我不需要 utc 选项,所以我最终使用了:
private dayJs(input?: any, format?: string, locale?: string): Dayjs {
return dayjs(input, format, locale);
}
parse(value: any, parseFormat: string): Dayjs | null {
if (value && typeof value === 'string') {
const longDateFormat = dayjs().localeData().longDateFormat(parseFormat); // MM/DD/YYY or DD-MM-YYYY, etc.
// return this.dayJs(value, longDateFormat);
let parsed = this.dayJs(value, longDateFormat, this.locale);
if (parsed.isValid()) {
// string value is exactly like long date format
return parsed;
}
const alphaNumericRegex = /[\W_]+/;
if (!alphaNumericRegex.test(value)) {
// if string contains no non-word characters and no _
// user might have typed 24012020 or 01242020
// strip long date format of non-word characters and take only the length of the value so we get DDMMYYYY or DDMM etc
const format = longDateFormat.replace(/[\W_]+/g, '').substr(0, value.length);
parsed = this.dayJs(value, format, this.locale);
if (parsed.isValid()) {
return parsed;
}
}
const userDelimiter = alphaNumericRegex.exec(value) ? alphaNumericRegex.exec(value)![0] : '';
const localeDelimiter = alphaNumericRegex.exec(longDateFormat) ? alphaNumericRegex.exec(longDateFormat)![0] : '';
const parts = value.split(userDelimiter);
const formatParts = longDateFormat.split(localeDelimiter);
if (parts.length <= formatParts.length && parts.length < 4) {
// right now this only works for days, months, and years, if time should be supported this should be altered
let newFormat = '';
parts.forEach((part, index) => {
// get the format in the length of the part, so if a the date is supplied 1-1-19 this should result in D-M-YY
// note, this will not work if really weird input is supplied, but that's okay
newFormat += formatParts[index].substr(0, part.length);
if (index < parts.length - 1) {
newFormat += userDelimiter;
}
});
parsed = this.dayJs(value, newFormat);
if (parsed.isValid()) {
return parsed;
}
}
// not able to parse anything sensible, return something invalid so input can be corrected
return this.dayJs(null);
}
return value ? this.dayJs(value).locale(this.locale) : null;
}
如果您只想在指定输入旁边支持仅数字输入(如 28082021),则需要带有 !alphaNumericRegex.test(value) 的 if 语句。这段代码从您的格式化字符串中取出任何分隔符(如 - 或/),并确保支持仅包含天或天和月的字符串(例如 28 或 2808)。它将使用当前月份和年份来填充缺失值。如果您只想支持完整的日-月-年字符串,您可以省略 .substr 部分。
关于angular-material - 使用 Material dayjs 日期适配器处理分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65687460/
我是 angular 的新手,想动态地更改 angular Material 主题,我知道如何通过制作 scss 文件来制作不同的主题,定义 3 种颜色,包括 mat 属性和功能,但后来我在 angu
我猜,是不允许在 Material 网格(嵌套网格)中放置 Material 网格吗? 有人可以确认我的假设吗? (我正在使用 Angular Material 6。) l
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我一直在 material-ui react 库中看到对名为“LeftNav ”的组件的引用(例如: Material UI - Open LeftNav / Drawer on AppBar cli
我正在使用 mat-list而且我无法在移动设备上滚动它。 它是一个 mat-nav-list,里面有一些 mat-list-item,我的列表结构类似于: dashboard
我是网络开发的新手,正在尝试使用 material-ui。我看到一些演示代码使用 withStyle,还有一些使用 withTheme。它们之间有什么区别吗?非常感谢! 最佳答案 我认为接受的答案没有
我正在研究 Material 设计和 Material 设计中描述的一些指南。 我似乎遗漏了一个部分(不确定是否应该涵盖),即 Google 如何处理 Fieldsets。该文档确实涵盖了各个输入,但
我正在根据到目前为止所学的知识使用 Material 设计创建一个示例应用程序,但我注意到 Material 设计的开箱即用字体对于不同的组件是不同的。对于 Material 对话框中的 Materi
我确实有角度 6,尽管 ng generate @angular/material:material-nav --name home不工作 得到类似的错误 Collection "@angular/m
我正在使用图书馆 material-table对于我的应用程序中的数据表。我将数据 Prop 设置为使用来自 this.state.data 的数据,并且添加行将通过使用 setState 在我的表上
如何在 Angular Material Design 中设置工具栏下方的侧导航?这样 sidenav 就不会越过工具栏.. 最佳答案 这是一个布局问题。只需使用此页面结构:
我使用的是角 Material 2,但我认为这也适用于角 Material 1。 假设我想使用角度 Material 选项卡,但我想隐藏选项卡或向其添加一些特定样式。 所以我有以下 html/angu
我安装了 material-ui“^1.0.0-beta.36”。文档说有日期选择器。 但我在 node_modules\material-ui 和任何子文件夹中都找不到它。 更改日志表明计划在未来版
从一小时前开始,我在 Material 设计图标 cdn 上不断收到网络错误,因为错误名称未解析。 http://cdn.materialdesignicons.com/5.4.55/css/mate
如何在不失去波纹效果的情况下更改角 Material 开关按钮的颜色? 请在此处查看代码笔:http://codepen.io/shyambhiogade/pen/LpNGBP 我已将颜色更改为 #0
对于textfield并选择,我看到我们具有以下选项来添加variant =“ outlined”。 但是,我看不到material-ui / DatePicker。有人可以建议如何使用实质性UI将v
在 3.1.0 版本中使用“@material-ui/core” 全局覆盖步进器图标的颜色非常容易全局 createMuiTheme({ overrides: { MuiStepIco
我在我的应用程序脚本插件中使用 materializecss,当我尝试动态添加工具提示时,提示不会使用新标签更新。我尝试了几种变体,甚至仔细检查了小费是否正在改变,确实如此。问题是它似乎没有用更新的文
有谁知道当模式确定时如何在 Material 进度微调器中显示不完整的部分。现在我是这样的 . 但我想要这样 最佳答案 这可以做到,但它主要是一个黑客。这个想法是使用一个带有与微调器匹配的边框的 di
我今天发现了这个很棒的 UI 框架,并花了很多时间浏览文档,我必须说,我已经爱上了它。现在我想将它用于一个中等规模的项目,但我有两个顾虑: 我找不到任何网格系统,我该如何进行布局? 如何让它响应? 我
我是一名优秀的程序员,十分优秀!