[英]How to maintain vertical scroll when updating Angular 5 data table?
我想經常使用從JSON REST API中提取的新數據更新我的數據表(具有多個ng-template
Covalent td-data-table
)。 比瀏覽器更多的行,因此用戶可能需要垂直滾動。 但是當我更新表格中的數據時,它會完全重繪,即垂直滾動位置重置到頂部,工具提示閃爍等等。
黑客可以保存/恢復垂直滾動,例如下面的工作,但是它們會造成很多視覺混亂,特別是在Firefox中。
// save vertical scroll
this.scrollTop = this.tableElt.nativeElement.querySelector('.td-data-table-scrollable').scrollTop;
// update table data here
this.data = newData;
// restore vertical scroll
setImmediate(() => {
this.tableElt.nativeElement.querySelector('.td-data-table-scrollable').scrollTop = this.scrollTop;
}
});
如何干凈地更新表格(或任何組件)中的數據,而不是黑客重置滾動位置並忍受大量閃爍行為?
如果沒有使用Covalent數據表的解決方案,是否有另一個Angular 2+控件可以正確處理?
您可以嘗試使用trackBy函數。 此函數將用於確定*ngFor
哪些行已更改以優化重繪。
<tbody>
<tr td-data-table-row *ngFor="let row of basicData; trackBy: getRowId">
<td td-data-table-cell *ngFor="let column of columns" [numeric]="column.numeric">
{{column.format ? column.format(row[column.name]) : row[column.name]}}
</td>
<td td-data-table-cell (click)="openPrompt(row, 'comments')">
<button mat-button [class.mat-accent]="!row['comments']">{{row['comments'] || 'Add Comment'}}</button>
</td>
</tr>
</tbody>
然后在你的打字稿中:
getRowById(index, row) {
// Return some unique primitive idenitifier (string, number, etc.)
return row['some unique property'];
}
有關trackBy
更多信息, trackBy
查看:
https://netbasal.com/angular-2-improve-performance-with-trackby-cc147b5104e5 https://blog.angular-university.io/angular-2-ngfor/
此外,NGX-Datatable非常適合這種用例。 它內置了虛擬滾動功能。 https://github.com/swimlane/ngx-datatable
我建議你切換到角度材料並將其綁定到一個可觀察的數據源。
https://material.angular.io/components/table/overview#observable-stream-of-data-arrays
當使用新數據更新數據源(Observable)時,它將更新DOM,並且不需要跟隨滾動事件。
如果您擔心頁面上列出的項目數量支持以簡單的方式分頁; 。 https://material.angular.io/components/table/overview#pagination
SideNote:切換到角度材料,因為它們的組件已有詳細記錄,包含示例和示例代碼如果您遇到問題,請告訴我。
看起來當你獲得更多數據時,你正在刷新整個列表(* ngFor中使用的數組),因此angular再次重新繪制全表。 嘗試僅將差異數據推送到該陣列。
將數據推送到* ng所使用的相同數組變量不會重新呈現html。
簡單的例子: https : //angular-frjdnf.stackblitz.io
編輯:
我使用* ngFor創建了一個帶共價表的示例項目,只更新了角度,而不是重新渲染整個表格。
鏈接到Stackblitz.io示例項目 。
HTML
<button (click)="addData()">Add Data</button>
<table td-data-table>
<thead>
<tr td-data-table-column-row>
<td td-data-table-column *ngFor="let column of columns">
{{column.label}}
</td>
</tr>
</thead>
<tbody>
<tr td-data-table-row *ngFor="let row of basicData">
<td td-data-table-cell *ngFor="let column of columns">
{{ row[column.name] }}
</td>
</tr>
</tbody>
</table>
TS
basicData
具有加載到表中的初始數據,我只是在點擊“添加數據”按鈕時將一些虛擬數據推送到basicData
,以便測試滾動條。
import { Component } from '@angular/core';
import { ITdDataTableColumn } from '@covalent/core/data-table';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
columns: ITdDataTableColumn[] = [
{ name: 'first_name', label: 'First Name' },
{ name: 'last_name', label: 'Last Name' },
{ name: 'gender', label: 'Gender' }
];
count = 0;
basicData: any[] = [
{
"first_name": "Sully",
"gender": "Male",
"last_name": "Clutterham"
},
...
]
additionalData: any[] = [
{
"first_name": "Sully",
"gender": "Male",
"last_name": "Clutterham"
},
...
]
addData(){
if(this.count >= this.additionalData.length)
this.count = 0;
this.basicData.push(this.additionalData[this.count]);
this.count++;
}
}
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.