经过几天的研究和实验,我似乎无法使用Angular Material的cdk-virtual-scroll-viewport
在Angular 8中复制以下典型的Instagram行为。
- 单击配置文件的图像网格中的图像 打开无限滚动的图像,
- 以单击的图像为中心,同时在其下方和上方加载上一个和下一个图像。
问题具体在于打开以单击的图像为中心的虚拟滚动。
我的设置:
- 配置文件组件加载带有
*ngFor="let post of posts"
的图像网格 - 单击时,将启动一个新的时间轴组件,接收上述
posts
数组作为[state]='{ data: posts }'
状态,以及单击的帖子的数组位置。 - 一切正常,提要(我称之为时间线(已加载,但是尽管我可以使用
this.viewPort.scrollToIndex(index)
使其滚动到单击的帖子位置,但我无法直接在此位置加载。
为什么我不希望它简单地滚动到那里,尽管它几乎是即时的?因为点击帖子之前的所有高清图像都将从服务器中提取,以便在提要滚动时加载。想象一下,如果点击的帖子之前有 20 个其他图片帖子。
我还尝试过什么:
我尝试在点击的帖子之前剪切帖子数组,用*cdkVirtualFor="let post of posts"
加载数组的第二部分(从他点击的帖子开始(,然后在posts
开头推动数组的第一部分,以便它将加载到首屏以上。但是,当数组的第一部分以posts
开头时,视图导航到页面顶部(第一篇文章(,而不是将前缀的帖子加载到首屏上方,这就是我想要的。
任何关于如何使这种巫术发挥作用的想法将不胜感激。
我仍然没有找到从点击的帖子开始渲染的方法,但我找到的最佳解决方法如下。
事实证明,使用this.viewPort.scrollToIndex(scrollIndex, "auto")
- 注意auto
参数 - 实际上并没有滚动页面,而是直接传送到所需的索引。这意味着,如果您足够快地调用该方法,则不会从服务器加载页面开头和您登陆的索引之间的其他项目。您可以在此 StackBlitz 中查看此实验,并打开 chrome 开发工具上的"网络"选项卡。
现在,尝试按预期方式运行上述命令,如下所示:
ngAfterViewInit() {
this.viewPort.scrollToIndex(i);
}
您可能会发现它不起作用。此处提供了此错误的两种解决方案。它们都可以工作,但调用setTimeout()
明显变慢,因为您实际上会在页面加载时看到新索引的"对齐"。因此,处理此问题的最佳方法是在ngAfterViewChecked()
钩子而不是ngAfterViewInit()
中运行scrollToIndex()
方法,如下所示:
ngAfterViewChecked() {
this.viewPort.scrollToIndex(i);
}
这不是一个完美的解决方案,但它实际上确实将所需的体验复制到最终用户。