【问题标题】:How to load and show large amounts of data in a table using Angular 2?如何使用 Angular 2 在表格中加载和显示大量数据?
【发布时间】:2016-10-20 13:42:12
【问题描述】:

我正在开发一个 Angular 2 应用程序,它必须以可滚动的方式显示大量数据 表。

数据在我的组件类中的一个数组中:

export class AppComponent { 

    clients: any[] = [];

    constructor(){
        for (var i = 0; i < 10; ++i) {
           this.clients.push({
               id: i,
               name: 'Client' + i,
               address: 'Address of client ' + i,
               phone: '(51) 5454-4646'
           });
        }
    }
}

然后在我的布局中通过 ngFor 加载数据:

       <div style="height:600px;overflow:scroll">

          <data-table>

          <th>Id</th>
          <th>Name</th>
          <th>Address</th>
          <th numeric>Phone</th>

          <tr *ngFor="let client of clients">
            <td>{{ client.id }}</td>
            <td>{{ client.name }}</td>
            <td>{{ client.address }}</td>
            <td>{{ client.phone}}</td>
          </tr>

        </data-table>
      </div>  

例如,它必须将数据加载到一个有 10.000 行、可能有 20.000 行和大约 10 列的表中。这里的问题是加载速度很慢,加载后运行延迟很严重。

在这种情况下我不能使用分页,并且滚动是强制性的。我想保持滚动拇指的大小和位置,就好像所有数据都已加载一样,即使我需要做一些技巧,比如只加载部分数据。

我想知道在不减速的情况下完成这项任务的最佳做法是什么。

【问题讨论】:

  • 试试 Material Virtual Scroll

标签: typescript angular html-table


【解决方案1】:

我建议您将表格转换为组件,并将更改检测策略更改为“推送”。 这样,Angular 将降低性能成本。

【讨论】:

    【解决方案2】:

    正如您所提到的,这是相当多的数据,并且对用户来说代价高昂,因为浏览器必须请求和下载大量数据。

    我建议将数据分成小节并添加分页。每页仅显示约 100 条记录。它将提高可读性和用户体验。

    在 Angular 1.x.x 中,您可以使用 limitTo 过滤器来限制结果。在 Angular 2.x.x 中,您可以使用 slice 过滤器。

    您更新后的模板可能如下所示。我不能保证这会奏效,但它会展示基本方法。

          <th>Id</th>
          <th>Name</th>
          <th order="desc">Address</th>
          <th numeric>Phone</th>
          <th>Ações</th>
    
          <tr *ngFor="let client of clients | slice:pageStart:100">
            <td>{{ client.id }}</td>
            <td>{{ client.name }}</td>
            <td>{{ client.address }}</td>
            <td>{{ client.phone}}</td>
            <td>Ações</td>
          </tr>
    
          <button *ngIf="pageStart >= 100" (click)="prevData()">Previous</button>
          <button *ngIf="pageStart < clients.length" (click)="NextData()">Next</button>
        </data-table>
    

    组件看起来像这样

    export class DataTable {
      // Code omitted for brevity
      pageStart = 0;
    
      nextData() {
        this.pageStart += 100;           // Get the next 100 records
      }
    
      prevData() {
        this.pageStart -= 100;          // Get the previous 100 records
      }
    }
    

    您也可以使用某种形式的infinite scrolling

    【讨论】:

    • 分页是我的第一个想法,但不幸的是我的老板不想为这个任务分页。分页是指指向表格下方每个页面的链接,就像在引导分页器中或在您的示例中一样。事实上,我必须按需加载数据,但使用滚动而不是分页器。我尝试了 1000 行,它运行顺利。 5000 不是。我需要类似于无限滚动的东西,但用户必须能够通过使用滚动拇指跳到表格的某些部分。
    • 我喜欢这种方法,尽管缺少微小的部分。尽管如此,这是一个很好的起点。用ngx-bootstrap 进行了一次很棒的合并:-)
    【解决方案3】:

    有点晚了,但我希望我能帮助其他路过的人。
    我正在使用 Richard Hamilton 的分页示例,并进行了一些更改。

    或者,您可以使用某种形式的无限滚动。

           <div style="height:600px;overflow:scroll" (scroll)="onScroll($event)">
    
          <data-table>
    
          <th>Id</th>
          <th>Name</th>
          <th>Address</th>
          <th numeric>Phone</th>
    
          <tr *ngFor="let client of clients | slice:pageStart:pageEnd">
            <td>{{ client.id }}</td>
            <td>{{ client.name }}</td>
            <td>{{ client.address }}</td>
            <td>{{ client.phone}}</td>
          </tr>
    
        </data-table>
      </div>  
    

    唯一的区别是滚动事件监听器和没有分页按钮。

    export class DataTable {
      pageStart:number = 0;
      pageEnd:number = 100;
      pageHeight:number = 30;
      pageBuffer:number = 100;
    
      onScroll( event, doc )
      {
        const scrollTop = event.target.scrollTop;
        const scrollHeight = event.target.scrollHeight;
        const offsetHeight = event.target.offsetHeight;
        const scrollPosition = scrollTop + offsetHeight;
        const scrollTreshold = scrollHeight - this.pageHeight;
        if( scrollPosition > scrollTreshold ){
          this.pageEnd+= this.pageBuffer;
        }
      }
    }
    

    脚本检查位置并调整 pageEnd 直到它到达末尾。
    在某些时候,此解决方案也会减慢速度。

    我只需要无限滚动解决方案,所以我只能告诉你我对没有减速问题的解决方案的想法。

    为防止出现此问题,您需要确保 rowHeight 已修复。
    现在您可以计算所有行的最大高度。
    创建一个具有高度的附加元素以确保滚动可用。
    设置位置:固定;在数据表中。
    这样可以确保表格始终可见。
    现在计算 pageStart 和 pageEnd 的位置。
    Slice 将负责渲染。

    我认为这可行,但我还没有测试过。 我也不知道这对于日常使用是否会是一个很好的解决方案。

    祝你好运。 :)

    【讨论】:

    猜你喜欢
    • 2015-04-28
    • 2017-08-09
    • 2012-02-24
    • 1970-01-01
    • 2022-01-20
    • 2011-02-18
    • 2021-02-16
    • 2014-03-24
    • 1970-01-01
    相关资源
    最近更新 更多