使用 Moment Js 在 Angular 中显示日历视图
Display a Calendar View in Angular Using Moment Js
我正在尝试使用 angular 从头开始创建日历视图。我已经完成了动态显示月份的所有日期。我的问题是我需要使用我在互联网上搜索过的 Moment 为周末日期(例如周五和周六)显示不同的背景颜色,我找不到任何资源来帮助我解决这个问题。除此之外,我需要在第一行内显示日期,而不是在我的日历视图中显示为单独的一行。
我的appcomponent.html代码
<div class="flex-container flex-center">
<button
mat-icon-button
matTooltip="Previous Month"
[matTooltipPosition]="'above'"
class="iconsSize ml-1 my-auto"
(click)="previousmonth()"
>
<mat-icon>
chevron_left
</mat-icon>
</button>
<h4><b>{{date.format('MMMM ')}}{{date.format('YYYY ')}}</b></h4>
<span class="material-icons" style="padding: 7px; font-size: 20px;">
event
</span>
<button
mat-icon-button
matTooltip="Next Month"
[matTooltipPosition]="'above'"
class="iconsSize ml-1 my-auto"
(click)="nextmonth()"
>
<mat-icon>
chevron_right
</mat-icon>
</button>
</div>
<div class="container-fluid">
<div class="flex-container flex-wrap p-3 m-2">
<div *ngFor ="let day of daysarr">
<div class="calendar-days flex-container flex-center">{{day}}</div>
</div>
</div>
</div>
我的appcomponent.ts文件
export class AppComponent implements OnInit {
public date = moment();
public daysarr;
constructor() { }
ngOnInit(): void {
this.daysarr = this.createCalendar(this.date);
}
createCalendar(month)
{
let firstDay = moment(month).startOf('M');
let days = Array.apply(null,{length: month.daysInMonth()+1})
.map(Number.call, Number)
.slice(1);
for(let n=0; n < firstDay.weekday(); n++)
{
days.unshift(null);
}
return days;
}
public nextmonth()
{
this.date.add(1,'M');
this.daysarr = this.createCalendar(this.date);
}
public previousmonth()
{
this.date.subtract(1,'M');
this.daysarr = this.createCalendar(this.date);
}
}
appcomponent.css
.calendar-days {
width: 155px;
height: 120px;
background: #fff;
border: 1px solid #ccc;
padding: 3px;
}
.flex-container {
display: -webkit-flex;
display: flex;
}
.flex-center {
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
我的输出:
我需要的输出是:
如果你想给特定的日子上色,你可以使用(我假设你的日子对象是一个 momentJs 对象):
<div [ngClass]="{ 'weekend': (day.day() === 5) || (day.day() === 6) }"
class="calendar-days flex-container flex-center">
{{day}}
</div>
然后将周末 class 添加到您的 css:
.weekend {
background-color: gray
}
希望下面的代码对您有所帮助。但更进一步,您可以考虑使用 the date picker
.calendar-days {
width: 155px;
height: 120px;
background: #fff;
border: 1px solid #ccc;
padding: 3px;
&.previous-month,
&.next-month {
color: grey;
}
&.weekend {
background-color: rgb(245, 245, 245);
}
}
.flex-container {
display: -webkit-flex;
display: flex;
}
.flex-center {
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
并调整html
<div class="flex-container flex-center">
<button
mat-icon-button
matTooltip="Previous Month"
[matTooltipPosition]="'above'"
class="iconsSize ml-1 my-auto"
(click)="previousmonth()"
>
<mat-icon>
chevron_left
</mat-icon>
</button>
<h4><b>{{date.format('MMMM ')}}{{date.format('YYYY ')}}</b></h4>
<span class="material-icons" style="padding: 7px; font-size: 20px;">
event
</span>
<button
mat-icon-button
matTooltip="Next Month"
[matTooltipPosition]="'above'"
class="iconsSize ml-1 my-auto"
(click)="nextmonth()"
>
<mat-icon>
chevron_right
</mat-icon>
</button>
</div>
<div *ngFor="let calendarItem of calendar; let i = index">
<div class="flex-container flex-center">
<div class="calendar-days" [class.weekend]="day.isWeekend" [ngClass]="day.className" *ngFor="let day of calendarItem">
<div *ngIf="i === 0">{{day.dayName}}</div>
{{day.day}}
</div>
</div>
</div>
最后在ts组件中
interface CalendarItem {
day: string;
dayName: string;
className: string;
isWeekend: boolean;
}
export class AppComponent implements OnInit {
date = moment();
calendar: Array<CalendarItem[]> = [];
ngOnInit(): void {
this.calendar = this.createCalendar(this.date);
}
createCalendar(month: moment.Moment) {
const daysInMonth = month.daysInMonth();
const startOfMonth = month.startOf('months').format('ddd');
const endOfMonth = month.endOf('months').format('ddd');
const weekdaysShort = moment.weekdaysShort();
const calendar: CalendarItem[] = [];
const daysBefore = weekdaysShort.indexOf(startOfMonth);
const daysAfter = weekdaysShort.length - 1 - weekdaysShort.indexOf(endOfMonth);
const clone = month.startOf('months').clone();
if (daysBefore > 0) {
clone.subtract(daysBefore, 'days');
}
for (let i = 0; i < daysBefore; i++) {
calendar.push(this.createCalendarItem(clone, 'previous-month'));
clone.add(1, 'days');
}
for (let i = 0; i < daysInMonth; i++) {
calendar.push(this.createCalendarItem(clone, 'in-month'));
clone.add(1, 'days');
}
for (let i = 0; i < daysAfter; i++) {
calendar.push(this.createCalendarItem(clone, 'next-month'));
clone.add(1, 'days');
}
return calendar.reduce((pre: Array<CalendarItem[]>, curr: CalendarItem) => {
if (pre[pre.length - 1].length < weekdaysShort.length) {
pre[pre.length - 1].push(curr);
} else {
pre.push([curr]);
}
return pre;
}, [[]]);
}
createCalendarItem(data: moment.Moment, className: string) {
const dayName = data.format('ddd');
return {
day: data.format('DD'),
dayName,
className,
isWeekend: dayName === 'Sun' || dayName === 'Sat'
};
}
public nextmonth() {
this.date.add(1, 'months');
this.calendar = this.createCalendar(this.date);
}
public previousmonth() {
this.date.subtract(1, 'months');
this.calendar = this.createCalendar(this.date);
}
}
我正在尝试使用 angular 从头开始创建日历视图。我已经完成了动态显示月份的所有日期。我的问题是我需要使用我在互联网上搜索过的 Moment 为周末日期(例如周五和周六)显示不同的背景颜色,我找不到任何资源来帮助我解决这个问题。除此之外,我需要在第一行内显示日期,而不是在我的日历视图中显示为单独的一行。 我的appcomponent.html代码
<div class="flex-container flex-center">
<button
mat-icon-button
matTooltip="Previous Month"
[matTooltipPosition]="'above'"
class="iconsSize ml-1 my-auto"
(click)="previousmonth()"
>
<mat-icon>
chevron_left
</mat-icon>
</button>
<h4><b>{{date.format('MMMM ')}}{{date.format('YYYY ')}}</b></h4>
<span class="material-icons" style="padding: 7px; font-size: 20px;">
event
</span>
<button
mat-icon-button
matTooltip="Next Month"
[matTooltipPosition]="'above'"
class="iconsSize ml-1 my-auto"
(click)="nextmonth()"
>
<mat-icon>
chevron_right
</mat-icon>
</button>
</div>
<div class="container-fluid">
<div class="flex-container flex-wrap p-3 m-2">
<div *ngFor ="let day of daysarr">
<div class="calendar-days flex-container flex-center">{{day}}</div>
</div>
</div>
</div>
我的appcomponent.ts文件
export class AppComponent implements OnInit {
public date = moment();
public daysarr;
constructor() { }
ngOnInit(): void {
this.daysarr = this.createCalendar(this.date);
}
createCalendar(month)
{
let firstDay = moment(month).startOf('M');
let days = Array.apply(null,{length: month.daysInMonth()+1})
.map(Number.call, Number)
.slice(1);
for(let n=0; n < firstDay.weekday(); n++)
{
days.unshift(null);
}
return days;
}
public nextmonth()
{
this.date.add(1,'M');
this.daysarr = this.createCalendar(this.date);
}
public previousmonth()
{
this.date.subtract(1,'M');
this.daysarr = this.createCalendar(this.date);
}
}
appcomponent.css
.calendar-days {
width: 155px;
height: 120px;
background: #fff;
border: 1px solid #ccc;
padding: 3px;
}
.flex-container {
display: -webkit-flex;
display: flex;
}
.flex-center {
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
我的输出:
我需要的输出是:
如果你想给特定的日子上色,你可以使用(我假设你的日子对象是一个 momentJs 对象):
<div [ngClass]="{ 'weekend': (day.day() === 5) || (day.day() === 6) }"
class="calendar-days flex-container flex-center">
{{day}}
</div>
然后将周末 class 添加到您的 css:
.weekend {
background-color: gray
}
希望下面的代码对您有所帮助。但更进一步,您可以考虑使用 the date picker
.calendar-days {
width: 155px;
height: 120px;
background: #fff;
border: 1px solid #ccc;
padding: 3px;
&.previous-month,
&.next-month {
color: grey;
}
&.weekend {
background-color: rgb(245, 245, 245);
}
}
.flex-container {
display: -webkit-flex;
display: flex;
}
.flex-center {
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
并调整html
<div class="flex-container flex-center">
<button
mat-icon-button
matTooltip="Previous Month"
[matTooltipPosition]="'above'"
class="iconsSize ml-1 my-auto"
(click)="previousmonth()"
>
<mat-icon>
chevron_left
</mat-icon>
</button>
<h4><b>{{date.format('MMMM ')}}{{date.format('YYYY ')}}</b></h4>
<span class="material-icons" style="padding: 7px; font-size: 20px;">
event
</span>
<button
mat-icon-button
matTooltip="Next Month"
[matTooltipPosition]="'above'"
class="iconsSize ml-1 my-auto"
(click)="nextmonth()"
>
<mat-icon>
chevron_right
</mat-icon>
</button>
</div>
<div *ngFor="let calendarItem of calendar; let i = index">
<div class="flex-container flex-center">
<div class="calendar-days" [class.weekend]="day.isWeekend" [ngClass]="day.className" *ngFor="let day of calendarItem">
<div *ngIf="i === 0">{{day.dayName}}</div>
{{day.day}}
</div>
</div>
</div>
最后在ts组件中
interface CalendarItem {
day: string;
dayName: string;
className: string;
isWeekend: boolean;
}
export class AppComponent implements OnInit {
date = moment();
calendar: Array<CalendarItem[]> = [];
ngOnInit(): void {
this.calendar = this.createCalendar(this.date);
}
createCalendar(month: moment.Moment) {
const daysInMonth = month.daysInMonth();
const startOfMonth = month.startOf('months').format('ddd');
const endOfMonth = month.endOf('months').format('ddd');
const weekdaysShort = moment.weekdaysShort();
const calendar: CalendarItem[] = [];
const daysBefore = weekdaysShort.indexOf(startOfMonth);
const daysAfter = weekdaysShort.length - 1 - weekdaysShort.indexOf(endOfMonth);
const clone = month.startOf('months').clone();
if (daysBefore > 0) {
clone.subtract(daysBefore, 'days');
}
for (let i = 0; i < daysBefore; i++) {
calendar.push(this.createCalendarItem(clone, 'previous-month'));
clone.add(1, 'days');
}
for (let i = 0; i < daysInMonth; i++) {
calendar.push(this.createCalendarItem(clone, 'in-month'));
clone.add(1, 'days');
}
for (let i = 0; i < daysAfter; i++) {
calendar.push(this.createCalendarItem(clone, 'next-month'));
clone.add(1, 'days');
}
return calendar.reduce((pre: Array<CalendarItem[]>, curr: CalendarItem) => {
if (pre[pre.length - 1].length < weekdaysShort.length) {
pre[pre.length - 1].push(curr);
} else {
pre.push([curr]);
}
return pre;
}, [[]]);
}
createCalendarItem(data: moment.Moment, className: string) {
const dayName = data.format('ddd');
return {
day: data.format('DD'),
dayName,
className,
isWeekend: dayName === 'Sun' || dayName === 'Sat'
};
}
public nextmonth() {
this.date.add(1, 'months');
this.calendar = this.createCalendar(this.date);
}
public previousmonth() {
this.date.subtract(1, 'months');
this.calendar = this.createCalendar(this.date);
}
}