typescript 如何使用 Angular 2 在表中加载和显示大量数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37903240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to load and show large amounts of data in a table using Angular 2?
提问by Natanael
I'm developing an Angular 2 app which must to show a large amount of data in a scrollable table.
我正在开发一个 Angular 2 应用程序,它必须在可滚动表中显示大量数据。
The data is in a array in my component class:
数据位于我的组件类中的数组中:
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'
});
}
}
}
Then the data is loaded through a ngFor in my layout:
然后数据通过我的布局中的 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>
For example, It must load data in a table with 10.000, maybe, 20.000 rows, and around 10 columns. The problem here is that it is very slow to load and after load it runs with a terrible lag.
例如,它必须在具有 10.000,也许,20.000 行和大约 10 列的表中加载数据。这里的问题是加载速度非常慢,加载后运行时滞后很严重。
I cannot use pagination in this case and the scroll is mandatory. I would like to keep the scroll thumb size and position as if all data is loaded even if I need to do a trick like load just part of the data.
在这种情况下我不能使用分页,滚动是强制性的。我想保持滚动拇指的大小和位置,就像加载了所有数据一样,即使我需要做一个技巧,比如只加载部分数据。
I would like to know what is the best praticce to do this task without slowdowns.
我想知道在不减速的情况下完成这项任务的最佳实践是什么。
回答by Ido
I would recomand you to convert your table into a component, and to change the change detection strategy into "on push". That way, Angular will reduce performance cost.
我建议您将表格转换为组件,并将更改检测策略更改为“on push”。这样,Angular 将降低性能成本。
回答by Richard Hamilton
As you mentioned, this is quite a lot of data and will be expensive to the users as the browser's will have to request and download a large amount of data.
正如您所提到的,这是相当多的数据,并且对用户来说是昂贵的,因为浏览器将不得不请求和下载大量数据。
I would recommend breaking the data down into subsections and adding pagination. Only show about 100 records per page. It will improve readability and the user experience as well.
我建议将数据分解成小节并添加分页。每页仅显示大约 100 条记录。它将提高可读性和用户体验。
In Angular 1.x.x, you could use the limitTo
filter to limit the results. In Angular 2.x.x, you can use the slice
filter.
在 Angular 1.xx 中,您可以使用limitTo
过滤器来限制结果。在 Angular 2.xx 中,您可以使用slice
过滤器。
Your updated template might look something like this. I can't guarantee this will work, but it will show the basic approach.
您更新的模板可能看起来像这样。我不能保证这会起作用,但它会显示基本方法。
<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>
The component would look something like this
该组件看起来像这样
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
}
}
Alternatively you could use some form of infinite scrolling
.
或者,您可以使用某种形式的infinite scrolling
.
回答by Orgoth Dorngree
A little bit late, but i hope i can help other people coming by.
I am using the pagination example by Richard Hamilton with some changes.
有点晚了,但我希望我能帮助到其他人。
我正在使用 Richard Hamilton 的分页示例,并进行了一些更改。
Alternatively you could use some form of infinite scrolling.
或者,您可以使用某种形式的无限滚动。
<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>
The only differences are a scroll eventlistener and no pagination buttons.
唯一的区别是滚动事件侦听器和没有分页按钮。
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;
}
}
}
The script checks the position and will adjust the pageEnd until it reaches the end.
At some point this solution will also slow down.
脚本检查位置并调整 pageEnd 直到它到达末尾。
在某些时候,此解决方案也会减慢速度。
I only needed the infinite scrolling solution, so i can only tell you my idea about a solution without the slow down problem.
我只需要无限滚动解决方案,所以我只能告诉你我对没有减速问题的解决方案的想法。
To prevent this problem you need to make sure the rowHeight is fixed.
Now you can calculate the maximum height of all rows.
Create a additional element with the height to make sure the scrolling is availible.
Set position:fixed; at the Data-Table.
This makes sure the Table is always visible.
Now calculate the position for pageStart and pageEnd.
Slice will take care of the rendering.
为了防止这个问题,你需要确保 rowHeight 是固定的。
现在您可以计算所有行的最大高度。
创建一个具有高度的附加元素以确保滚动可用。
设置位置:固定;在数据表。
这可确保表格始终可见。
现在计算 pageStart 和 pageEnd 的位置。
Slice 将负责渲染。
I think this could work, but i have not tested it yet. I also don't know if this will be a good solution for daily use.
我认为这可以工作,但我还没有测试过。我也不知道这是否是日常使用的好解决方案。
Good luck at all. :)
祝你好运。:)