Angular перерендер таблицы
Есть таблица, из Material библиотеки которая подключена к WebSocket и получает данные в среднем раз в 500мс. Все данные в колонке - динамические, значения любого столбца как и кол-во строк могут измениться в любой момент.
Проблема. В таблице появилась кнопка, а так как она все время перерендеривается, то и кнопка вместе с ней, в результате она срабатывает через раз:
<table mat-table [dataSource]="rows">
<ng-container matColumnDef="empty">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="displayedColumns.length">
<span>Пусто</span>
</td>
</ng-container>
<ng-container matColumnDef="percent">
<th mat-header-cell *matHeaderCellDef> Процент </th>
<td mat-cell *matCellDef="let row">
{{ row.percent }}
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> Закрыть </th>
<td mat-cell *matCellDef="let element">
<button
(click)="closeDialog(element)"
mat-mini-fab color="warn">
<mat-icon style="color: white">
disabled_by_default
</mat-icon>
</button>
</td>
</ng-container>
<tr mat-footer-row *matFooterRowDef="!rows.length ? ['empty'] : []" class="empty"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
WebSocket получает все состояние таблицы целиком и целиком присваивает весь массив
this.streamService
.subscribe((data) => {
this.rows = data.items;
});
Какие есть возможные пути решения данной проблемы?
Ответы (1 шт):
Чтобы уменьшить число DOM операций, можно добавить в input mat-table функцию trackBy. Как минимум те строки, которые не обновились не будут рендериться на каждый чих.
Но проблема явно внутри бизнес-логики. Рендер строк раз в полсекунды - это прям беда. Как минимум закрывай все диалоги, когда приходят новые данные. Вот прям в подписке. Тогда не будет вопросов, что клик хендлер сработает для элемента, которого уже может не быть.