角度在将注入的服务用于角度日历时不会检测到参考对象的变化



所以我使用的是Angular-Calendar,并且在按下按钮时有一个对话框,现在我在日历服务事件数组中添加一个随机事件对象以进行测试:

 onButtonClick() {
      var date = addHours(new Date(), 2)
      this.calendarService.onCreateEvent('test added',date )
      console.log(date)
    }

将其添加到我的注射服务中:

export class CalendarService {
  events: CalendarEvent[] = [
    { title: "my test event 1", start: new Date() },
    { title: "my test event 2", start: addDays(new Date(), 1) }
  ];

现在,我使用ngonit在组件中设置本地事件数组:

export class ScheduleCalendarComponent implements OnInit{
  constructor(
    private calendarService: CalendarService,
    public dialog: MatDialog
  ) {}
  view: string = "month";
  viewDate: Date = new Date();
  events: CalendarEvent[] = [];
  refresh: Subject<any> = new Subject();
  ngOnInit(): void {
    this.events = this.calendarService.events;
  }

因此,现在它会拉出正确的事件,但是当我添加一个事件时,它不会更新DOM,因为我仅更新阵列OnInit方法:

  onCreateEvent(title: string, start: any) {
    this.events = [...this.events, {title: title, start: start}]
  }

我使用它,然后将其添加到日历中:

 <mwl-calendar-day-view
    *ngSwitchCase="'day'"
    [viewDate]="viewDate"
    [events]="this.calendarService.events"
    (hourSegmentClicked)="openDialog()"
  >
  </mwl-calendar-day-view>

但是,我该如何使用组件自己的数组而不是服务数组来执行此操作?组件像Max一样使用自己的数组而不是直接从服务中拿走自己的数组,这是更好的做法吗?

我想使用组件阵列进行此操作,但它不会在按钮上进行更新:

 <mwl-calendar-day-view
    *ngSwitchCase="'day'"
    [viewDate]="viewDate"
    [events]="events"
    (hourSegmentClicked)="openDialog()"
  >
  </mwl-calendar-day-view>

希望有意义

谢谢!

发生了这种情况,因为有不同的更改访问策略,而您看到的是changeDetectionStrategy.onPush下的CC_1

changeDetection: ChangeDetectionStrategy.OnPush

为什么不使用

创建新的数组副本
ngOnInit(): void {
  this.events = [...this.calendarService.events];
}

ngOnInit(): void {
  this.events = JSON.parse(JSON.stringify(this.calendarService.events));
}

然后您不会修改服务阵列events,并且可以轻松使用:

onCreateEvent(title: string, start: any) {
 this.events = [...this.events, {title: title, start: start}]
}

我知道这是一个古老的问题,但是这是我的解决方案,可以帮助某些人:

  1. 您首先使用对受试者的订阅,可观察到的任何西装

  2. 您确保通过使用以下内容来迫使日历以刷新其视图:

    export class MyComponentWithCalendarComponent implements OnInit, AfterViewInit, OnDestroy {
      @ViewChild(MatCalendar) calendar: MatCalendar<Date>;
      private subscription = new Subscription();
      data: Stuff[]
      ...
      ngAfterViewInit() {
        this.subscription.add(
        // remember this can be something else, like this.service.getStuff().subscribe({...
        this.stuffSubject.subscribe({
          next: (data: Stuff[]) => {
            this.data = data;
            // if your changes concern same month
            this.calendar.updateTodaysDate()
            // if your changes concern other months. this is what fixed the issue in my case =>
            const activeDate = new Date()
            this.calendar.activeDate = activeDate
          }
    }
    

我创建了一个有关此=&gt的问题;线上" startat"缺少用于更改检测的,因为我认为当我们期望更改时应包括@Input字段。"活跃的"

,至少是我的最佳知识。

最新更新