Use cases/Query params filters — URL как состояние фильтров
Use cases · 19 実
Query params filters — URL как состояние фильтров
Паттерн
Таблица с фильтрами и пагинацией. Пользователь хочет поделиться ссылкой, чтобы коллега открыл точно такое же состояние. Значит, фильтры должны жить в URL (?q=rxjs&page=2), а форма и URL должны быть синхронизированы.
Какую проблему решаем
Два источника правды — форма и URL — нужно держать в согласии. Если делать это императивно, легко получить бесконечный цикл: форма обновила URL, URL обновил форму, форма снова обновила URL. Или наоборот — отправлять navigate с тем же состоянием, дёргая историю браузера на каждый чих.
Операторы и зачем они нужны
combineLatest — объединяет фильтры формы и query params в одно состояние.
map + ключ-строка — нормализуем состояние в каноническую строку (q=rxjs&page=2). По строке легко сравнить.
distinctUntilChanged с comparator по этому ключу — пропускаем только реально новое состояние, ломая цикл.
tap — синхронизация URL как side effect.
Подводные камни
distinctUntilChanged() без comparator не сработает — объект form value создаётся заново на каждое изменение, ссылочное сравнение всегда вернёт false.
Не путайте этот поток с потоком загрузки данных. Сначала синхронизируем URL ↔ фильтры, отдельным потоком грузим данные по нормализованному состоянию.
Если в tap мутировать исходный объект — comparator станет непредсказуемым. Только чистые операции.
Что в итоге получаем
URL и фильтры остаются в одном каноническом состоянии. Ссылкой можно поделиться, история браузера не засоряется дубликатами.