cdkVirtual для не рендеринга новых предметов - PullRequest
4 голосов
/ 27 марта 2019

Я строю календарь с вертикальной прокруткой.Я получаю начальные дни для загрузки, но когда новые дни добавляются в список, они не отображаются.

<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

Ответы [ 4 ]

1 голос
/ 06 апреля 2019

Я понял это.

Первоначально, я добавлял новые дни, захватывая текущее значение, как это

let items = this.items$.value;
items.push(newItem);
this.items$.next(items)

Очевидно, это фактически мутация значения *Значение 1006 *, поэтому не создается новый массив для возврата и не запускается обнаружение изменений.

Я изменил его на

let items = [...this.items$.value];
items.push(newItem);
this.items$.next(items)

и все хорошо.

Итак, хотя ответы здесь верны в том смысле, что я изменял исходный массив, мне нужна была информация , вызывающая next() с измененной версией * Текущее значение BehaviorSubject не выдает новый массив.Событие emit не гарантирует неизменность.

0 голосов
/ 27 марта 2019

*cdkVirtualFor будет обновляться только при неизменном обновлении, т. Е. Вы не можете обновить массив после его инициализации.Мы используем оператор распространения, чтобы получить то, что вы ищете.

Проверьте это очень просто stackblitz ... здесь я использовал 2 метода, которые вы можете попробовать и посмотреть:

*Метод 1007 * addCountryOld изменяет массив, помещая объект в наш массив, и, следовательно, отображаемое представление не обновляется. addCountryNew метод использует неизменяемость через оператор распространения, что приводит к отображаемому представлениюобновляется.

Это код для addCountryNew :

addCountryNew(){
    let  newObj = {'name':'stack overflow country', "code":'SO'};
    this.myList = [...this.myList, newObj];
  }
0 голосов
/ 05 апреля 2019

Вместо

this.days = days;

do

this.days = [...days];

Работает.https://stackblitz.com/edit/material-infinite-calendar-amcapx?file=src/app/calendar/calendar.component.ts

(Но значит ли это, что BehaviorSubject продолжает использовать и изменять один и тот же объект? Странно!)

0 голосов
/ 27 марта 2019

Это можно сделать так:

Вы можете инициализировать другую переменную как наблюдение вашего поведения субъекта "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();
  }

А затем подпишитесь на то, что можно наблюдать в calender.component.ts внутри ngOnInit, например:

this._daysService.dayObs$.subscribe(days => {
  this.days = days;
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...