mwl-calendar-month-view [events]值更改后的角度刷新视图

问题描述

我有一个HTML标签,其中显示日历:

 <mwl-calendar-month-view
    *ngSwitchCase="'month'"
    [viewDate]="viewDate"
    [events]="eventsValue"
  >

“ eventsValue”是CalendarEvent []值的获取器。我通过REST调用获取日历事件。然后我订阅获得的可观察的。在“订阅”内部,我做一些逻辑并根据响应创建新的CalendarEvent []。然后,我将新创建的变量分配给HTML文件中使用的变量。我期望的是,当HTML中使用的变量的值更改时,视图将刷新。但是效果是日历试图刷新,但是它发生在我从REST调用中观察到“订阅”的那一刻。有什么想法可以正确刷新事件的更新值并使它在视图中可见吗?调用REST并更新CalendarEvents []的函数

  public fetchCalendarData() {
    const loggedUser = this.userService.getLoggedUser();
    if (loggedUser) {
      this.calendarService.fetchCalendarData(loggedUser).subscribe((response) => {

        // some logic with response

        this.eventsValue = [{
          title: 'title',start: new Date(),end: new Date()
        }];
      });
    }
  }

调试屏幕截图,以查看日历视图何时尝试刷新自身(我想这是我收到有关“事件”为“未定义”的警告的时刻):

debug - calendar refresh moment

然后在执行“订阅”之后,我在控制台中调用了“ this.events”,但我不明白为什么它仍未定义(我只是看到了在“订阅”中更新的值)。

解决方法

尝试注入对组件ChangeDetector的引用,并通过调用detectChanges()(从组件及其所有子组件运行更改检测)或markForCheck()(显式地)触发更改检测。将组件和所有父组件标记到根,以进行更改检测。

constructor(private changeDetectorRef: ChangeDetectorRef) {}

---8<----

public fetchCalendarData() {
    const loggedUser = this.userService.getLoggedUser();
    if (loggedUser) {
      this.calendarService.fetchCalendarData(loggedUser).subscribe((response) => {

        // some logic with response

        this.eventsValue = [{
          title: 'title',start: new Date(),end: new Date()
        }];

        // trigger change-detection
        this.changeDetectorRef.detectChanges();
      });
    }
  }

为防止mwl-calendar-month-view抱怨undefined [事件]输入:

<ng-container *ngIf="eventsValue">
    <mwl-calendar-month-view
        *ngSwitchCase="'month'"
        [viewDate]="viewDate"
        [events]="eventsValue"
    >
</ng-container>
,

基于@Clemens Sum注释,我将@Component批注中的changeDetection从ChangeDetectionStrategy.OnPush更改为ChangeDetectionStrategy.Default,它可以正常工作。谢谢!

,

以上答案都不适合我。但是,我找到了解决方案。

mwl-calendar 有一个 refresh 属性,它将 Subject 作为一个值。向 Subject 发送值将触发刷新操作。

以下示例具有包含上一个/今天/下一个按钮和可点击日期的月度视图。单击一天将添加一个事件并刷新日历视图。我在 CSS 中使用 Bootstrap 5。

calendar.component.html

<div class="calendar">
  <h1>{{viewDate | date: 'MMMM'}}</h1>
  <div class="row text-center">
    <div class="col-md-4">
      <div class="btn-group">
        <div class="btn btn-primary" mwlCalendarPreviousView [view]="view" [(viewDate)]="viewDate">Previous</div>
        <div class="btn btn-outline-secondary" mwlCalendarToday [(viewDate)]="viewDate">Today</div>
        <div class="btn btn-primary" mwlCalendarNextView [view]="view" [(viewDate)]="viewDate">Next</div>
       </div>
     </div>
   </div>
   <mwl-calendar-month-view [viewDate]="viewDate (dayClicked)="dayClicked($event.day)" [events]="events" [refresh]="refreshCalendar"></mwl-calendar-month-view>
</div>

calendar.component.ts

import { Component,OnInit } from '@angular/core';
import { CalendarEvent,CalendarView } from 'angular-calendar';
import { Subject } from 'rxjs';

export class CalendarComponent implements OnInit {

  viewDate: Date = new Date();
  view: CalendarView = CalendarView.Month;
  CalendarView = CalendarView;
  events: CalendarEvent[] = [];
  refreshCalendar: Subject<void> = new Subject();

  ...

  dayClicked({ date,events }: { date: Date; events: CalendarEvent[] }) {
    this.events.push({
      start: date,title: 'Some title'
    });
    this.refreshCalendar.next();
  }

结果应该是这样的:

Example showcase