Angular 完整日历视图

Posted

技术标签:

【中文标题】Angular 完整日历视图【英文标题】:Angular Full calendar View 【发布时间】:2022-01-16 17:23:49 【问题描述】:

我在我的项目中使用了一个角度完整的日历,我已经尝试过这个https://mattlewis92.github.io/angular-calendar/#/kitchen-sink。 但在这方面,我遇到了一些错误。

这是我的 html 代码

 <div class="row text-center">
                            <div class="col-md-4">
                              <div class="btn-group">
                                <div
                                  class="btn btn-primary"
                                  mwlCalendarPreviousView
                                  [view]="view"
                                  [(viewDate)]="viewDate"
                                  (viewDateChange)="closeOpenMonthViewDay()"
                                >
                                  Previous
                                </div>
                                <div
                                  class="btn btn-outline-secondary"
                                  mwlCalendarToday
                                  [(viewDate)]="viewDate"
                                >
                                  Today
                                </div>
                                <div
                                  class="btn btn-primary"
                                  mwlCalendarNextView
                                  [view]="view"
                                  [(viewDate)]="viewDate"
                                  (viewDateChange)="closeOpenMonthViewDay()"
                                >
                                  Next
                                </div>
                              </div>
                            </div>
                            <div class="col-md-4">
                              <h3> viewDate | calendarDate:(view + 'ViewTitle'):'en' </h3>
                            </div>
                            <div class="col-md-4">
                              <div class="btn-group">
                                <div
                                  class="btn btn-primary"
                                  (click)="setView(CalendarView.Month)"
                                  [class.active]="view === CalendarView.Month"
                                >
                                  Month
                                </div>
                                <div
                                  class="btn btn-primary"
                                  (click)="setView(CalendarView.Week)"
                                  [class.active]="view === CalendarView.Week"
                                >
                                  Week
                                </div>
                                <div
                                  class="btn btn-primary"
                                  (click)="setView(CalendarView.Day)"
                                  [class.active]="view === CalendarView.Day"
                                >
                                  Day
                                </div>
                              </div>
                            </div>
                          </div>
                          <br />
                          <div [ngSwitch]="view">
                            <mwl-calendar-month-view
                              *ngSwitchCase="CalendarView.Month"
                              [viewDate]="viewDate"
                              [events]="events"
                              [refresh]="refresh"
                              [activeDayIsOpen]="activeDayIsOpen"
                              (dayClicked)="dayClicked($event.day)"
                              (eventClicked)="handleEvent('Clicked', $event.event)"
                              (eventTimesChanged)="eventTimesChanged($event)"
                            >
                            </mwl-calendar-month-view>
                            <mwl-calendar-week-view
                              *ngSwitchCase="CalendarView.Week"
                              [viewDate]="viewDate"
                              [events]="events"
                              [refresh]="refresh"
                              (eventClicked)="handleEvent('Clicked', $event.event)"
                              (eventTimesChanged)="eventTimesChanged($event)"
                            >
                            </mwl-calendar-week-view>
                            <mwl-calendar-day-view
                              *ngSwitchCase="CalendarView.Day"
                              [viewDate]="viewDate"
                              [events]="events"
                              [refresh]="refresh"
                              (eventClicked)="handleEvent('Clicked', $event.event)"
                              (eventTimesChanged)="eventTimesChanged($event)"
                            >
                            </mwl-calendar-day-view>
                          </div>
                          
                          <!-- Everything you see below is just for the demo, you don't need to include it in your app -->
                          
                          <br /><br /><br />
                          
                          <h3>
                            Edit events
                            <button class="btn btn-primary float-right" (click)="addEvent()">
                              Add new
                            </button>
                            <div class="clearfix"></div>
                          </h3>
                          
                          <div class="table-responsive">
                            <table class="table table-bordered">
                              <thead>
                                <tr>
                                  <th>Title</th>
                                  <th>Primary color</th>
                                  <th>Secondary color</th>
                                  <th>Starts at</th>
                                  <th>Ends at</th>
                                  <th>Remove</th>
                                </tr>
                              </thead>
                          
                              <tbody>
                                <tr *ngFor="let event of events">
                                  <td>
                                    <input
                                      type="text"
                                      class="form-control"
                                      [(ngModel)]="event.title"
                                      (keyup)="refresh.next()"
                                    />
                                  </td>
                                  <td>
                                    <input
                                      type="color"
                                      [(ngModel)]="event.color.primary"
                                      (change)="refresh.next()"
                                    />
                                  </td>
                                  <td>
                                    <input
                                      type="color"
                                      [(ngModel)]="event.color.secondary"
                                      (change)="refresh.next()"
                                    />
                                  </td>
                                  <td>
                                    <input
                                      class="form-control"
                                      type="text"
                                      mwlFlatpickr
                                      [(ngModel)]="event.start"
                                      (ngModelChange)="refresh.next()"
                                      [altInput]="true"
                                      [convertModelValue]="true"
                                      [enableTime]="true"
                                      dateFormat="Y-m-dTH:i"
                                      altFormat="F j, Y H:i"
                                      placeholder="Not set"
                                    />
                                  </td>
                                  <td>
                                    <input
                                      class="form-control"
                                      type="text"
                                      mwlFlatpickr
                                      [(ngModel)]="event.end"
                                      (ngModelChange)="refresh.next()"
                                      [altInput]="true"
                                      [convertModelValue]="true"
                                      [enableTime]="true"
                                      dateFormat="Y-m-dTH:i"
                                      altFormat="F j, Y H:i"
                                      placeholder="Not set"
                                    />
                                  </td>
                                  <td>
                                    <button class="btn btn-danger" (click)="deleteEvent(event)">
                                      Delete
                                    </button>
                                  </td>
                                </tr>
                              </tbody>
                            </table>
                          </div>
                          
                          <ng-template #modalContent let-close="close">
                            <div class="modal-header">
                              <h5 class="modal-title">Event action occurred</h5>
                              <button type="button" class="close" (click)="close()">
                                <span aria-hidden="true">&times;</span>
                              </button>
                            </div>
                            <div class="modal-body">
                              <div>
                                Action:
                                <pre> modalData?.action </pre>
                              </div>
                              <div>
                                Event:
                                <pre> modalData?.event | json </pre>
                              </div>
                            </div>
                            <div class="modal-footer">
                              <button type="button" class="btn btn-outline-secondary" (click)="close()">
                                OK
                              </button>
                            </div>
                          </ng-template>

这是我的 component.ts 代码

import 
  
  ChangeDetectionStrategy,
  ViewChild,
  TemplateRef,
 from '@angular/core';
import 
  startOfDay,
  endOfDay,
  subDays,
  addDays,
  endOfMonth,
  isSameDay,
  isSameMonth,
  addHours,
 from 'date-fns';
import  Subject  from 'rxjs';
import  NgbModal  from '@ng-bootstrap/ng-bootstrap';
import 
  CalendarEvent,
  CalendarEventAction,
  CalendarEventTimesChangedEvent,
  CalendarView,
 from 'angular-calendar';

const colors: any = 
  red: 
    primary: '#ad2121',
    secondary: '#FAE3E3',
  ,
  blue: 
    primary: '#1e90ff',
    secondary: '#D1E8FF',
  ,
  yellow: 
    primary: '#e3bc08',
    secondary: '#FDF1BA',
  ,
;
// declare let $:any;
// declare var jQuery: any;
@Component(
  selector: 'app-attendance',
  changeDetection: ChangeDetectionStrategy.OnPush,
  templateUrl: './attendance.component.html',
  styleUrls: ['./attendance.component.scss']
)



 
export class AttendanceComponent implements OnInit 

  @ViewChild('modalContent',  static: true )
  modalContent!: TemplateRef<any>;

  view: CalendarView = CalendarView.Month;

  CalendarView = CalendarView;

  viewDate: Date = new Date();

  modalData!: 
    action: string;
    event: CalendarEvent;
  ;

  actions: CalendarEventAction[] = [
    
      label: '<i class="fas fa-fw fa-pencil-alt"></i>',
      a11yLabel: 'Edit',
      onClick: ( event :  event: CalendarEvent ): void => 
        this.handleEvent('Edited', event);
      ,
    ,
    
      label: '<i class="fas fa-fw fa-trash-alt"></i>',
      a11yLabel: 'Delete',
      onClick: ( event :  event: CalendarEvent ): void => 
        this.events = this.events.filter((iEvent) => iEvent !== event);
        this.handleEvent('Deleted', event);
      ,
    ,
  ];

  refresh = new Subject<void>();

  events: CalendarEvent[] = [
    
      start: subDays(startOfDay(new Date()), 1),
      end: addDays(new Date(), 1),
      title: 'A 3 day event',
      color: colors.red,
      actions: this.actions,
      allDay: true,
      resizable: 
        beforeStart: true,
        afterEnd: true,
      ,
      draggable: true,
    ,
    
      start: startOfDay(new Date()),
      title: 'An event with no end date',
      color: colors.yellow,
      actions: this.actions,
    ,
    
      start: subDays(endOfMonth(new Date()), 3),
      end: addDays(endOfMonth(new Date()), 3),
      title: 'A long event that spans 2 months',
      color: colors.blue,
      allDay: true,
    ,
    
      start: addHours(startOfDay(new Date()), 2),
      end: addHours(new Date(), 2),
      title: 'A draggable and resizable event',
      color: colors.yellow,
      actions: this.actions,
      resizable: 
        beforeStart: true,
        afterEnd: true,
      ,
      draggable: true,
    ,
  ];

  activeDayIsOpen: boolean = true;


  dayClicked( date, events :  date: Date; events: CalendarEvent[] ): void 
    if (isSameMonth(date, this.viewDate)) 
      if (
        (isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) ||
        events.length === 0
      ) 
        this.activeDayIsOpen = false;
       else 
        this.activeDayIsOpen = true;
      
      this.viewDate = date;
    
  

  eventTimesChanged(
    event,
    newStart,
    newEnd,
  : CalendarEventTimesChangedEvent): void 
    this.events = this.events.map((iEvent) => 
      if (iEvent === event) 
        return 
          ...event,
          start: newStart,
          end: newEnd,
        ;
      
      return iEvent;
    );
    this.handleEvent('Dropped or resized', event);
  

  handleEvent(action: string, event: CalendarEvent): void 
    this.modalData =  event, action ;
    this.modal.open(this.modalContent,  size: 'lg' );
  

  addEvent(): void 
    this.events = [
      ...this.events,
      
        title: 'New event',
        start: startOfDay(new Date()),
        end: endOfDay(new Date()),
        color: colors.red,
        draggable: true,
        resizable: 
          beforeStart: true,
          afterEnd: true,
        ,
      ,
    ];
  

  deleteEvent(eventToDelete: CalendarEvent) 
    this.events = this.events.filter((event) => event !== eventToDelete);
  

  setView(view: CalendarView) 
    this.view = view;
  

  closeOpenMonthViewDay() 
    this.activeDayIsOpen = false;
  

这是我的 module.ts 文件

import  CalendarModule, DateAdapter  from 'angular-calendar';
import  adapterFactory  from 'angular-calendar/date-adapters/date-fns';
import  NgbModalModule  from '@ng-bootstrap/ng-bootstrap';
import  FormsModule  from '@angular/forms';

 imports: [
    BrowserModule,
    CalendarModule.forRoot(
      provide: DateAdapter,
      useFactory: adapterFactory,
    ),
FormsModule,
NgbModalModule
],

我收到这样的错误消息。

error TS2532: Object is possibly 'undefined'.
[(ngModel)]="event.color.primary"

Object is possibly 'undefined'.
[(ngModel)]="event.color.secondary"
                                                                  
 Can't bind to 'altInput' since it isn't a known property of 'input'.
[altInput]="true"

Can't bind to 'enableTime' since it isn't a known property of 'input'. [enableTime]="true"

Can't bind to 'convertModelValue' since it isn't a known property of 'input'.
[convertModelValue]="true"

谁能帮我解决这些错误?

【问题讨论】:

【参考方案1】:

关于event.color.primary 的错误应该是结果,您的颜色是any 类型并且没有定义特定类型。 尝试创建一个IColors 接口并将primarysecondary 条目定义为字符串。

关于input标签的错误,是由于输入HTML元素的未知属性导致的。

【讨论】:

以上是关于Angular 完整日历视图的主要内容,如果未能解决你的问题,请参考以下文章

Angular-Ui-Calendar:如何在单个日历中显示两个agendaWeekView

Angular-ui 日历错误

如何将日历组件插入 Angular 2 应用程序?

如何将 jsonp 与 angular-ui 日历一起使用

Angular JS bootstrap ui日历问题

在渲染视图/模板之前等待 Angular 2 加载/解析模型