问题描述
<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()
}];
});
}
}
调试屏幕截图,以查看日历视图何时尝试刷新自身(我想这是我收到有关“事件”为“未定义”的警告的时刻):
然后在执行“订阅”之后,我在控制台中调用了“ 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();
}
结果应该是这样的: