Angular 角度cdk滚动:更新视图中未显示的数据源

Angular 角度cdk滚动:更新视图中未显示的数据源,angular,angular-material,angular-cdk,virtualscroll,Angular,Angular Material,Angular Cdk,Virtualscroll,到目前为止,我以前所有构建无限滚动条的尝试都失败了。 我目前正在使用的组件使用Angular的虚拟滚动,当达到虚拟滚动视口的某个索引时,应该更新数据源。 虽然BehaviorSubject确实得到了更新,但我无法在视图中看到新版本 我的组件如下所示: import {Day, Month, Selected, Weekday} from './datepicker'; import {CdkVirtualScrollViewport} from '@angular/cdk/scrolling';

到目前为止,我以前所有构建无限滚动条的尝试都失败了。 我目前正在使用的组件使用Angular的虚拟滚动,当达到虚拟滚动视口的某个索引时,应该更新数据源。 虽然BehaviorSubject确实得到了更新,但我无法在视图中看到新版本

我的组件如下所示:

import {Day, Month, Selected, Weekday} from './datepicker';
import {CdkVirtualScrollViewport} from '@angular/cdk/scrolling';
import {BehaviorSubject} from 'rxjs';

@Component({
  selector: 'app-calendar-datepicker',
  templateUrl: './calendar-datepicker.component.html',
  styleUrls: ['./calendar-datepicker.component.scss']
})
export class CalendarDatepickerComponent implements OnInit {
  months: BehaviorSubject<any[]> = new BehaviorSubject<any[]>([]);

  previousScrollIndex: number;

  @ViewChild('dateScroller') dateScroller: CdkVirtualScrollViewport;

  constructor() {
  }

  ngOnInit() {
    /*initialization of the array*/
    const initialMonths = [];
    const month = new Month(this.currentDate);
    const date = moment(this.currentDate);
    const nextMonth = new Month(date.add(1, 'M'));
    const nextDate = moment(date);
    const monthAfterNextMonth = new Month(nextDate.add(1, 'M'));
    initialMonths.push(month);
    initialMonths.push(nextMonth);
    initialMonths.push(monthAfterNextMonth);
    this.months.next(initialMonths);
  }

  public onScroll(index) {
    if (typeof(this.previousScrollIndex) === 'undefined') {
      this.previousScrollIndex = index;
    } else if (this.previousScrollIndex < index) {
      if (index % 2 === 0) {
        this.dateScroller.scrollToIndex(index);
      } else {
        this.dateScroller.scrollToIndex(index + 1);

        /*This is the place where the BehaviorSubject is updated*/
        const date = moment(this.months.value[index].date);
        const monthToFetch = new Month(date.add(2, 'M'));
        const fetchedMonths = this.months.value;
        fetchedMonths.push(monthToFetch);
        this.months.next(fetchedMonths);
      }
      this.previousScrollIndex = index;
    } else {
      if (index % 2 === 0) {
        this.dateScroller.scrollToIndex(index);
      } else {
        this.dateScroller.scrollToIndex(index - 1);
      }
     this.previousScrollIndex = index;
    }
  }
}
import{Day,Month,Selected,Weekday}来自“/datepicker”;
从“@angular/cdk/scrolling”导入{CdkVirtualScrollViewport};
从“rxjs”导入{BehaviorSubject};
@组成部分({
选择器:“应用程序日历日期选择器”,
templateUrl:'./calendar datepicker.component.html',
样式URL:['./日历日期选择器.component.scss']
})
导出类CalendarDatepickerComponent实现OnInit{
月份:行为主体=新行为主体([]);
索引:编号;
@ViewChild(“dateScroller”)dateScroller:CdkVirtualScrollViewport;
构造函数(){
}
恩戈尼尼特(){
/*数组的初始化*/
常量initialMonths=[];
const month=新月份(此.currentDate);
const date=时刻(此.currentDate);
const nextMonth=新月份(日期加1,'M');
const nextDate=时刻(日期);
const monthAfterNextMonth=新月份(nextDate.add(1,'M'));
初始月份。推送(月份);
初始月份推送(下一个月);
初始月份。推送(monthAfterNextMonth);
这个月。下一个月(初始月);
}
公共onScroll(索引){
if(typeof(this.previousScrollIndex)==“未定义”){
this.previousScrollIndex=索引;
}else if(this.previousScrollIndex
意见如下:

<cdk-virtual-scroll-viewport itemSize="92" #dateScroller class="scroll-container"
                             (scrolledIndexChange)="onScroll($event)">
  <div *cdkVirtualFor="let month of months | async">
    <div class="month">{{month.date.format('MMMM')}}</div>
    <div class="days">
      <div class="day previousMonth" *ngFor="let prevMonthDay of month.prevMonthDays"></div>
      <div class="day" *ngFor="let day of month.monthDays" (click)="onSelect(day)"
           [ngClass]="{ 'selected': day.selected, 'past': day.past, 'today': day.today,
       'first': day.firstSelected && isRangeSelected, 'last':day.lastSelected,
       'onlyOneSelected': day.firstSelected && !isRangeSelected}">
        <span *ngIf="day.firstSelected || day.lastSelected" class="borderDay"></span>
        <span class="dayText">{{day.number}}</span>
      </div>
    </div>
  </div>
</cdk-virtual-scroll-viewport>

{{month.date.format('MMMM')}
{{day.number}

到目前为止,我已经尝试使用ChangeDetectorRef并手动触发它,或者将我的代码放在一个
setTimeout()
-函数中更新
months
,但两者都不起作用。

我认为您的问题是,您正在将新的月份附加到同一数组中,因此对象引用不会改变。因此,Angular不需要重新渲染数据

尝试:


完成了任务,非常感谢!你无法想象你的回答对我有多重要!
const fetchedMonths = [...this.months.value, monthToFetch]