角度 - 如何打开以点击的图像为中心的虚拟滚动?



经过几天的研究和实验,我似乎无法使用Angular Material的cdk-virtual-scroll-viewport在Angular 8中复制以下典型的Instagram行为。

  1. 单击配置文件的图像网格中的图像
  2. 打开无限滚动的图像,
  3. 以单击的图像为中心,同时在其下方和上方加载上一个和下一个图像。

问题具体在于打开以单击的图像为中心的虚拟滚动。


我的设置:

  1. 配置文件组件加载带有*ngFor="let post of posts"的图像网格
  2. 单击时,将启动一个新的时间轴组件,接收上述posts数组作为[state]='{ data: posts }'状态,以及单击的帖子的数组位置。
  3. 一切正常,提要(我称之为时间线(已加载,但是尽管我可以使用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);
}

这不是一个完美的解决方案,但它实际上确实将所需的体验复制到最终用户。

最新更新