Angular Material Scroll загружает больше предметов, чем ожидалось
Я пытаюсь загрузить 20 элементов через компонент виртуальной прокрутки, но вижу 34, как только страница загружается, без какой-либо прокрутки. Я неправильно понял css? Или на контроле есть какая-то настройка, которую я забыл? Проект находится здесь.
2 ответа
Этот учебник по Firebase говорит:
Давайте начнем с рассмотрения нескольких важных концепций с виртуальной прокруткой. Сначала вы объявляете компонент cdk-virtual-scroll-viewport, чтобы обеспечить контекст для виртуальной прокрутки. У него должно быть свойство ввода itemSize, определяемое как высота пикселя каждого элемента.
Вы можете видеть, что это не сделано специально для видов прокрутки сетки, но мы можем обойти это ограничение:
У вас есть 5 столбцов с изображениями высотой 160 пикселей и полями сверху и снизу каждые 10 пикселей, что дает 180 пикселей.
Теперь мы рассчитываем 180 делится на 5 и получаем 36. Это itemSize
тебе нужно.
<cdk-virtual-scroll-viewport itemSize="36">
<div class="image" *cdkVirtualFor="let image of images">
<a (click)="viewDetail(image)">
<img src="https://picsum.photos/200/160/?image={{ image.id }}" />
</a>
</div>
</cdk-virtual-scroll-viewport>
Посмотрите на эту вилку вашего StackBlitz
Официальная документация здесь: Angular | Скроллинг
Вы также можете изменить размеры буфера
<cdk-virtual-scroll-viewport itemSize="36" minBufferPx="540" maxBufferPx="540">
<!-- ... -->
</cdk-virtual-scroll-viewport>
Смотрите: Угловой | Прокрутка # Прокрутка по элементам фиксированного размера
Вы также можете позволить Angular сделать математику:
<cdk-virtual-scroll-viewport itemSize="{{ 180 / 5 }}" minBufferPx="{{ 180 * 3 }}" maxBufferPx="{{ 180 * 3 * 3 }}">
Это означает, что вы заранее загрузите три страницы (3 строки на страницу) и загрузите больше, если останется только один буфер страниц (3 строки изображений на страницу)
Одна идея состоит в том, чтобы загрузить только пару элементов и использовать Observer для загрузки следующей группы элементов.
<cdk-virtual-scroll-viewport
itemSize="10"
minBufferPx="1200"
maxBufferPx="1200"
(scrolledIndexChange)="getNextBatch($event)">
...
</cdk-virtual-scroll-viewport>
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { ImageService } from '../image.service';
import { Subscription } from 'rxjs';
import { Router } from '@angular/router';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
@Component({
selector: 'app-gallery',
templateUrl: './gallery.component.html',
styleUrls: ['./gallery.component.css'],
})
export class GalleryComponent implements OnInit, OnDestroy {
@ViewChild(CdkVirtualScrollViewport) viewport: CdkVirtualScrollViewport;
constructor(public service: ImageService, private router: Router) {}
...
getNextBatch(e) {
const end = this.viewport.getRenderedRange().end;
const total = this.viewport.getDataLength();
console.log(end)
console.log(total)
if (end === total) {
console.log('request next batch');
}
}
}