Проблема с виртуальной прокруткой cdk

Кто-нибудь встречал проблему с виртуальной прокруткой angular 7 cdk, работающей ненормально в группе mat-tab.

https://github.com/angular/material2/issues/13981

Мой шаблон компонента города выглядит так

<cdk-virtual-scroll-viewport class="list-container" [itemSize]="50" minBufferPx="200" maxBufferPx="400" (scrolledIndexChange)="getNextBatch($event)">
  <div *cdkVirtualFor="let state of statesObservable | async; trackBy: trackByFn" class="list-group-item state-item">
    <div class="state">{{state.name}}</div>
    <div class="capital">{{state.capital}}</div>
  </div>
</cdk-virtual-scroll-viewport>

Когда этот компонент города помещается в группу mat-tab-group в качестве второй вкладки

<mat-tab-group>
  <mat-tab label="Country">
    <app-country></app-country>
  </mat-tab>
  <mat-tab label="City">
    <app-city></app-city>
  </mat-tab>
</mat-tab-group>

Результат выглядит как bel  введите описание изображения здесь ow:

Код stackblitz находится здесь: https://stackblitz.com/edit/angular7-virtual-scroll-issue

У кого-нибудь есть идеи по этой проблеме?


person rodent_la    schedule 08.11.2018    source источник


Ответы (5)


Вы говорите ему, что размер буфера должен находиться в диапазоне от 200 до 400 пикселей, но ваше окно прокрутки намного выше этого.

Измените минимальное и максимальное значение на 1200 пикселей, при этом элементы будут закрывать ваше окно просмотра, даже когда вы прокручиваете вниз для поиска дополнительных элементов.

https://stackblitz.com/edit/angular7-virtual-scroll-issue-ftcnng

person Per Hornshøj-Schierbeck    schedule 16.01.2019
comment
Обходным решением является изменение минимума и максимума. Поскольку имя атрибута - buffer, поэтому оно должно быть дополнительным к размеру области просмотра. - person rodent_la; 23.03.2019
comment
Это правильное решение для всех, кто сюда приходит. Спасибо! Я должен тебе кофе;) - person LppEdd; 11.04.2019
comment
Это неправильное решение. Это дополнительный буфер к области просмотра. - person itsundefined; 17.07.2019
comment
возможно, @itsundefined, но это не так, как это работает / работал в последний раз, когда я проверял - person Per Hornshøj-Schierbeck; 18.07.2019

Вам нужно отложить загрузку содержимого вкладки, объявив тело в ng-template с атрибутом matTabContent. Таким образом, размер области просмотра рассчитывается только при отображении вкладки.

  <mat-tab label="City">
    <ng-template matTabContent>
      <app-city></app-city>
    </ng-template>
  </mat-tab>

См .: https://material.angular.io/components/tabs/overview#lazy-loading

person Liviu    schedule 22.03.2019
comment
Это правильное решение, все остальные - в лучшем случае обходные пути. Спасибо! - person Johannes Stadler; 21.07.2020

Вопрос был задан некоторое время назад, но есть решение, которое не является обходным.

Сначала вам понадобится ссылка на окно просмотра:

@ViewChild(CdkVirtualScrollViewport, {static: false}) cdkVirtualScrollViewport: CdkVirtualScrollViewport;

Затем вы можете вызвать метод checkViewportSize(), когда размер области просмотра изменился. Перед вызовом этого метода вам необходимо обновить высоту стиля контейнера Viewport.

this.heightChange$.subscribe(() => {
    this.cdkVirtualScrollViewport.checkViewportSize();
});
person Simon Steinbeisser    schedule 19.11.2019

У меня работает, спасибо!

  @ViewChild(CdkVirtualScrollViewport) viewport: CdkVirtualScrollViewport;

  @HostListener('window:resize', ['$event'])
  onResize(event) {
    this.viewport.checkViewportSize();
  }
person Aleksandr Skobeltcyn    schedule 26.11.2019
comment
Что делать после вызова checkViewportSize() матода. - person Abhishek Mani; 14.02.2020
comment
В основном ничего, это просто решает проблему - person Aleksandr Skobeltcyn; 28.04.2020

Используйте только ItemSize. Избегайте максимального и минимального буфера.

<cdk-virtual-scroll-viewport class="list-container" [itemSize]="50" >

Это должна быть точная высота одного элемента в пикселях.

person Fred    schedule 07.12.2020