Как поддерживать вертикальную прокрутку при обновлении Таблицы данных Angular 5?
Я хотел бы часто обновлять таблицу данных (Covalent td-data-table
несколько ng-template
) С новыми данными, извлеченными из API REST JSON. Больше строк, чем поместится в браузере, поэтому пользователю может потребоваться прокрутка по вертикали. Но когда я обновляю данные в таблице, он полностью перерисовывается, т. е. вертикальное положение прокрутки сбрасывается наверх, всплывают подсказки и т. д..
хаки, например, сохранить / восстановить вертикальную прокрутку, такую как ниже вид работы, но они создают много визуального беспорядка, особенно в Браузер 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;
}
});
как я могу чисто обновить данные в таблице (или любой компонент на самом деле) без взлома, чтобы сбросить позиции прокрутки и мириться с большим количеством мигающего поведения?
Если нет решения с использованием ковалентной таблицы данных, есть ли другой угловой элемент управления 2+, который обрабатывает это правильно?
анимированный захват экрана проблемы: вертикальная прокрутка возвращается при обновлении данных. Вертикальная прокрутка должна поддерживаться между данными новинки.
4 ответов
Я предлагаю вам переключиться на угловой материал и привязать его к обозримому источников данных.
https://material.angular.io/components/table/overview#observable-stream-of-data-arrays
когда источник данных (наблюдаемый) обновляется новыми данными, он обновит DOM, и не будет необходимости следить за событиями прокрутки.
Если вы беспокоитесь о количестве элементов, перечисленных на странице, поддерживает разбиение на страницы простым способом; . https://material.angular.io/components/table/overview#pagination
SideNote: переключитесь на угловой материал, поскольку их компоненты хорошо документированы, с примерами и образцами кодов Дай мне знать, если застрянешь.
вы можете попробовать использовать функцию 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
проверьте:
https://netbasal.com/angular-2-improve-performance-with-trackby-cc147b5104e5 https://blog.angular-university.io/angular-2-ngfor/
также, фабриката необходмо предусмотреть-строительство объекта DataTable очень хорошо для этого случая использования. Он встроен в виртуальную прокрутку. https://github.com/swimlane/ngx-datatable
похоже, когда вы получаете больше данных, вы обновляете весь список(массив, используемый в *ngFor), поэтому angular снова рисует полную таблицу. Попробуйте поместить в этот массив только разностные данные.
нажатие данных на ту же переменную массива, которая используется *ngFor не будет повторно отображать html.
простой пример:https://angular-frjdnf.stackblitz.io
Edit:
Я сделал пример проекта с ковалентной таблицей, используя *ngFor с угловым обновлением только дополнительной строки и не перерисовывая всю таблицу.
ссылка на Стакблиц.образец 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++;
}
}
надеюсь, что это помогает.