縦スクロールのカレンダーを作成しています。最初の日をロードしていますが、新しい日がリストに追加されても、レンダリングされません。
<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
*cdkVirtualFor
は、不変に更新した場合にのみ更新されます。つまり、初期化後に配列を更新することはできません。スプレッド演算子を使用して、探しているものを取得します。
これを非常に簡単に確認してください stackblitz ...ここでは、2つの方法を使用して試してみることができます。
addCountryOld
メソッドは、オブジェクトを配列にプッシュすることで配列を変更するため、レンダリングされたビューは更新されません。addCountryNew
メソッドは、spread演算子を介して不変性を使用します。これにより、レンダリングされたビューが更新されます。これはaddCountryNewのコードです:
addCountryNew(){
let newObj = {'name':'stack overflow country', "code":'SO'};
this.myList = [...this.myList, newObj];
}
これは次のように実行できます。
別の変数を、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;
})