【问题标题】:Display a Calendar View in Angular Using Moment Js使用 Moment Js 在 Angular 中显示日历视图
【发布时间】:2020-11-30 07:21:04
【问题描述】:

我正在尝试使用 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;
    }

我的输出:

我需要的输出是:

【问题讨论】:

    标签: angular typescript momentjs


    【解决方案1】:

    希望下面的代码可以帮助到你。但更进一步,您可以考虑使用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);
      }
    }
    

    【讨论】:

    • 我能知道如何对每周日历视图执行相同的操作吗?每周日历视图只需要在一个页面中显示 7 天,然后点击右下角的 V 形应该显示下周
    • 是的,你可以。我创建了stackblitz.com/edit/angular-qftanr?file=src/app/…。代码看起来很丑,但希望你能明白
    • 嗨,我需要在日历的任何日期上选择完整的日期,比如如果我选择日期 26,我怎样才能获得完整的日期,比如 2022-04-26,并且可以使用 ISOstring 跨度>
    • 嗨@tauseef-arshad 您可以在CalendarItem 中添加更多属性,例如date: moment.Moment。你可以在这个stackblitz.com/edit/angular-qftanr?file=src/app/…中找到
    • 确定这对我有很大帮助,但是上面给出的选择日期链接中存在错误,它返回前一个日期,就像我选择 27 它在警报模式中返回 26 日期一样。看看谢谢
    【解决方案2】:

    如果你想为特定的日子着色,你可以使用(我假设你的 day 对象是一个 momentJs 对象):

    <div [ngClass]="{ 'weekend': (day.day() === 5) || (day.day() === 6) }"
         class="calendar-days flex-container flex-center">
         {{day}}
    </div>
    

    然后将周末课程添加到您的 CSS:

    .weekend {
      background-color: gray
    }
    

    【讨论】:

    • 不,它没有正确显示周末灰色对我来说是交替显示的,而不是固定到所有星期五和 Staurday。
    • 交替显示是什么意思?
    • 另外,为了确保,我已经更新了我的答案以准确显示 ngClass 指令的放置位置
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多