Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 不同固定大小项目的角度虚拟滚动策略_Angular_Angular Material_Angular Cdk_Angular Cdk Virtual Scroll - Fatal编程技术网

Angular 不同固定大小项目的角度虚拟滚动策略

Angular 不同固定大小项目的角度虚拟滚动策略,angular,angular-material,angular-cdk,angular-cdk-virtual-scroll,Angular,Angular Material,Angular Cdk,Angular Cdk Virtual Scroll,我正在使用Angular的cdk虚拟滚动视口显示一个无限的虚拟滚动。除了订阅视图位置,该功能不依赖于它的任何特殊功能,以便在用户滚动到底部时加载新元素(在自定义数据源中): connect(collectionViewer:collectionViewer):可观察{ this.viewChanges=collectionViewer.viewChange.subscribe((listRange)=>{ 此.loadItemsFor(列表范围); }); .. } 当所有项目都具有相同的高度

我正在使用Angular的
cdk虚拟滚动视口
显示一个无限的虚拟滚动。除了订阅视图位置,该功能不依赖于它的任何特殊功能,以便在用户滚动到底部时加载新元素(在自定义
数据源中)

connect(collectionViewer:collectionViewer):可观察{
this.viewChanges=collectionViewer.viewChange.subscribe((listRange)=>{
此.loadItemsFor(列表范围);
});
..
}
当所有项目都具有相同的高度时(在css和
itemSize
中指定)。现在我尝试添加不同类型的项目,其大小不同(比如
100px
50px
)。这对不起作用,因此我尝试了
cdl Experiative
(使用)中的
autosize
。但是,使用动态策略时,一旦将新元素添加到备份虚拟滚动的数据源中,滚动位置就会闪烁(我假设是因为
ItemAverager


有没有一种可行的方法来实现这两种策略的混合?我知道列表中每个项目的类型,因此它的高度,所以应该可以精确计算显示的内容和要加载的内容?当然,对于大型集合来说,它的性能可能不太好。

Angular
cdkVirtualFor
允许提供一个,这是您提到的固定高度和自动高度策略的实现方式。在您的情况下,它将接受项目高度数组作为输入。我最近不得不处理这个确切的情况:用户可以添加任意数量的项目并计算项目大小的列表表单,自定义虚拟滚动策略用于提高性能。为了了解虚拟滚动策略的内部工作原理,我发现深入研究Alex Inkin的固定和自动大小策略的源代码非常有帮助

下面是这样一个策略的外观。这基本上是一个简化的固定高度策略,但是使用高度计算而不是固定高度值

类CustomVirtualScrollStrategy实现VirtualScrollStrategy{
构造函数(私有ItemHeight:ItemHeight){}
专用视口?:CdkVirtualScrollViewport
私有scrolledIndexChange$=新主题()
public scrolledIndexChange:Observable=this.scrolledIndexChange$.pipe(distinctUntilChanged())
_minBufferPx=100
_maxBufferPx=100
附加(视口:CdkVirtualScrollViewport){
this.viewport=视口;
this.updateTotalContentSize()
this.updateRenderedRange()
}
分离(){
this.scrolledIndexChange$.complete()
删除此项。视口
}
公共更新itemHeights(itemHeights:itemHeights){
this.itemHeights=itemHeights
this.updateTotalContentSize()
this.updateRenderedRange()
}
私有getItemOffset(索引:编号):编号{
返回此.itemHeights.slice(0,索引).reduce((acc,itemHeights)=>acc+itemHeights,0)
}
私有getTotalContentSize():编号{
返回此.itemHeights.reduce((a,b)=>a+b,0)
}
私有getListRangeAt(scrollOffset:number,viewportSize:number):ListRange{
类型Acc={ItemIndexInsRange:number[],currentOffset:number}
常量visibleOffsetRange:Range=[scrollOffset,scrollOffset+viewportSize]
const itemsInRange=this.itemHeights.reduce,用于完整的工作实现

connect(collectionViewer: CollectionViewer): Observable<Item[]> {
  this.viewChanges = collectionViewer.viewChange.subscribe((listRange) => {
    this.loadItemsFor(listRange);
  });
  ..
}