web-dev-qa-db-ja.com

cdkVirtualForは新しいアイテムをレンダリングしません

縦スクロールのカレンダーを作成しています。最初の日をロードしていますが、新しい日がリストに追加されても、レンダリングされません。

<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>

BehaviorSubjectで日を更新するサービスがあります。日のリストが更新されていることは知っていますが、変更が検出されていないようです。

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

詳細については、StackBlitzリポジトリが公開されています https://stackblitz.com/edit/material-infinite-calendar

5
Will Luce

*cdkVirtualForは、不変に更新した場合にのみ更新されます。つまり、初期化後に配列を更新することはできません。スプレッド演算子を使用して、探しているものを取得します。

これを非常に簡単に確認してください stackblitz ...ここでは、2つの方法を使用して試してみることができます。

  • addCountryOldメソッドは、オブジェクトを配列にプッシュすることで配列を変更するため、レンダリングされたビューは更新されません。
  • addCountryNewメソッドは、spread演算子を介して不変性を使用します。これにより、レンダリングされたビューが更新されます。

これはaddCountryNewのコードです:

addCountryNew(){
    let  newObj = {'name':'stack overflow country', "code":'SO'};
    this.myList = [...this.myList, newObj];
  }
1
Akber Iqbal

これは次のように実行できます。

別の変数を、behaviorsubject "days $"の監視として初期化できます。

calendar-days.service.tsで

  public days$: BehaviorSubject<Date[]>;
  public dayObs$: Observable<Date[]>

  constructor() {
    this.days$ = new BehaviorSubject<Date[]>(this._initialDays);
    this.dayObs$ = this.days$.asObservable();
  }

そして、次のようにngOnInit内のcalender.component.tsで監視可能なものをサブスクライブします。

this._daysService.dayObs$.subscribe(days => {
  this.days = days;
})
0
Sumit Vekariya