Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: cdkVirtualFor not rendering new items

I'm building a vertically scrolling calendar. I'm getting the initial days to load, but when new days are added to the list, they aren't being rendered.

<cdk-virtual-scroll-viewport
  class="demo-viewport"
  [itemSize]="100"
  (onContentScrolled)="handleScrollChange($event)"
>
  <calendar-day
    *cdkVirtualFor="let day of days; trackBy: trackByFn"
    [day]="day"
  ></calendar-day>
</cdk-virtual-scroll-viewport>
<button (click)="goToToday()">go</button>

I have a service with a BehaviorSubject updating the days. I know the list of days is being updated, but the change doesn't seem to be detected.

  ngOnInit() {
    this._daysService.days$.subscribe(days => {
      this.days = days;
    })
    this.watchScroll();
    this.handleScrollingUp();
    this.handleScrollingDown();
  }

For more info, the StackBlitz repo is public https://stackblitz.com/edit/material-infinite-calendar

like image 400
Will Luce Avatar asked Mar 27 '19 03:03

Will Luce


Video Answer


1 Answers

I had a strange behavior with *cdkVirtualFor where it would not update even if I set the variable immutably as described in most of the answers above.

In my scenario if would not render the items when updated from an empty array to a non-empty array.

After spending a lot of time my last restore was to wrap cdk-virtual-scroll-viewport with an ng-container based on the existence of items.

<ng-container *ngIf="items.length">
      <cdk-virtual-scroll-viewport>
          <div *cdkVirtualFor="let item of items">
          ...
          </div>
      </cdk-virtual-scroll-viewport>
</ng-container>

This way the entire container was re-initialized when items became available. This solved my issue.

like image 71
parliament Avatar answered Oct 13 '22 10:10

parliament