Модуль 5 · урок 1 з 10
Анатомія таблиці
Таблиця — найчастіша задача в ентерпрайзі й перше, що дають новому фронтендеру на робочому проєкті. Виглядає нудно, але саме тут одночасно вилазять типізація, продуктивність, реактивні фільтри й порожні стани. Почнемо з того, з чого таблиця складається.
Частини
Стан таблиці — це один обʼєкт
export interface TableState {
page: number;
size: number;
sort: SortState[]; // масив — бо сортування багатоколонкове
query: string;
filters: Record<string, string>;
}
export interface SortState {
key: string;
dir: 'asc' | 'desc';
}
Це важлива думка, з якої варто почати модуль: сортування, фільтр і сторінка — це не три
різні механізми, а один стан. Зміна будь-якої частини дає новий набір рядків.
У сторі з модуля 4 це буде один BehaviorSubject<TableState> замість трьох.
// один потік замість трьох незалежних
readonly rows$ = combineLatest([this.allRows$, this.state$]).pipe(
map(([rows, state]) => applyState(rows, state)),
);
Коли змінюється фільтр, сторінку треба скинути на першу. Інакше користувач відфільтрував і бачить порожньо — бо він досі на сьомій сторінці, а результатів тепер два. Це найчастіший баг у гридах, і його не помічають, поки хтось не поскаржиться.
DataSource: посередник між даними й таблицею
В Angular Material таблиця не працює з масивом напряму. Вона працює з джерелом даних — обʼєктом, який уміє віддати потік рядків і прибрати за собою:
interface DataSource<T> {
connect(): Observable<readonly T[]>; // таблиця підписується при появі
disconnect(): void; // і відписується при знищенні
}
Це дає дві переваги. По-перше, таблиця нічого не знає про те, звідки беруться дані — з масиву, з HTTP, з WebSocket. По-друге, підписка керується самою таблицею, тож витоків з уроку 10 модуля 4 тут не буває.
Найпростіший варіант — MatTableDataSource, готовий клас із вбудованими
сортуванням, фільтром і пагінацією. Він зручний для швидкого старту, але має обмеження,
про які поговоримо в наступному уроці.
Що саме просить лід
Реалізувати насичену таблицю на Angular Material Table або AG-Grid: багатоколонкове сортування, клієнтська пагінація, динамічний пошук-фільтр і вибір рядків на строго типізованих моделях. Таблиця має плавно рендерити динамічні моковані потоки з повною типобезпекою, без лагів і витоків.
Розкладемо на пункти, кожному з яких присвячено окремий урок:
| Вимога | Урок | Головна складність |
|---|---|---|
| Багатоколонкове сортування | 5 | Стабільний компаратор і пріоритет колонок |
| Клієнтська пагінація | 4 | Скидання сторінки при зміні фільтра |
| Динамічний пошук | 6 | Debounce, нормалізація рядка, кілька фільтрів разом |
| Вибір рядків | 7 | «Усі на сторінці» проти «усі взагалі» |
| Строга типізація | 8 | Колонка не може посилатись на неіснуюче поле |
| Без лагів | 9 | OnPush, track, відсутність роботи в шаблоні |