顺利加载消息Angular 8

Posted

技术标签:

【中文标题】顺利加载消息Angular 8【英文标题】:Smoothly loading messages Angular 8 【发布时间】:2020-04-06 04:48:24 【问题描述】:

我正在使用 Angular 8 编写一个聊天应用程序,这就是我想要实现的目标: 我的代表两个用户之间聊天的对话组件在启动后会获得一页包含 10 条消息的最后消息。包含这些消息的 div 向下滚动到最后一条消息。当用户向上滚动并到达某个点时,会加载下一页。两个数组加入,用户现在看到 20 条消息。到目前为止,这是我所拥有的:

html

<div>
  <div #scrollMe [scrollTop]="scrollMe.scrollHeight" (scroll)="onScroll($event)" style="overflow-y: scroll; height: 400px;">
    <ul>
      <li *ngFor="let message of messages?.reverse()">
    </ul>
  </div>
</div>

打字员:

loadMessages(page: number, itemsPerPage?: number) 
    this.messageService.getMessageThread(page, itemsPerPage || 10)
      .subscribe((res: PaginatedResult<MessageThread>) => 
        if (this.messages == null) 
          this.messages = res.result.messages;
         else 
          this.messages = this.messages.concat(res.result.messages);
        
      );
  


onScroll(event) 
    if (event.target.scrollTop < 100) 
      if (this.pagination.currentPage >= this.pagination.totalPages) 
        return;
      

      this.loadMessages(++this.pagination.currentPage);
    
  

它可以工作,但问题是当我加入这两个数组时,我的滚动条跳得非常难看,因为我拿着滚动条它保持在同一位置并继续加载下一页。总的来说,我对 Angular 和前端非常陌生,所以我觉得我错过了一些东西。我试图找到任何现成的解决方案,但找不到。任何帮助将不胜感激。

请注意,我不想使用 JQuery。

【问题讨论】:

你能提供demo stackblitz吗? 【参考方案1】:

几件事:

首先,我们需要一个加载标志:

loading = false;

然后我们让loadMessages 返回一个可观察对象而不是处理结果:

  loadMessages(page: number, itemsPerPage?: number) 
    this.loading = true;
    return this.messageService.getMessageThread(page, itemsPerPage || 10);
  

一个单独的方法 handleResponse 通过将加载设置为 false 并连接消息来处理响应。

然后我们可以在滚动处理程序中考虑请求延迟,并使用加载标志来防止多个请求:

  onScroll(event) 
    // get the scroll height before adding new messages
    const startingScrollHeight = event.target.scrollHeight;
    if (event.target.scrollTop < 100) 
      if (this.pagination.currentPage >= this.pagination.totalPages) 
        return;
      

      else if (!this.loading) 
        this.loadMessages(this.pagination.currentPage).subscribe((res) => 
          this.handleResponse(res);
          // using setTimeout lets the app "wait a beat" so it can measure
          // new scroll height *after* messages are added
          setTimeout(() => 
            const newScrollHeight = this.scrollDiv.nativeElement.scrollHeight;
            // set the scroll height from the difference of the new and starting scroll height
            this.scrollDiv.nativeElement.scrollTo(0, newScrollHeight - startingScrollHeight);
          );
        );
      
    
  

Stackblitz(更新)

【讨论】:

嗨!谢谢您的回答。我几乎把头撞在墙上,试图理解为什么你的例子很完美,但它在我的项目中不起作用,然后我意识到了。我使用我的 API 来获取数据,而你正在模拟它。我 added a small delay in response 你的例子,它现在的行为就像它在我的项目中一样。 好的,我更新了我的答案和 stackblitz 以解决请求延迟问题。很好的收获

以上是关于顺利加载消息Angular 8的主要内容,如果未能解决你的问题,请参考以下文章

Angular Material Stepper 在首次加载时未定义

错误:.css 中的加载器未在 Angular 12.1.1 中返回字符串

Heroku 错误:页面是通过 HTTPS 加载的,但请求了一个不安全的脚本“angular-route.js”

系统 JS 不加载模块

当收到新消息而不重新加载视图时,如何将来自 stomp 客户端的消息显示到视图中

iframe跨域传值踩坑