Изучение
Как запрос навигации доходит до Flutter
Пять сущностей одного рабочего перехода, места их создания и минимальная зависимость функционального кода.
v1.1.0Начальный уровень
Как запрос навигации доходит до Flutter
Страница каталога открывает Product и ожидает результат покупки:
dart
final NavigationTicket<bool> ticket = context.readNavigation.push<bool>(
const ProductDestination('keyboard-42'),
);
В переходе участвуют пять сущностей. В обычном UI-коде нужны только Destination и NavigationPort.
| Сущность | Назначение | Где создаётся |
|---|---|---|
ProductDestination | Параметры и ожидаемый результат перехода | Функциональный код |
productRoute | Страница и URI для Destination | Навигационный модуль функциональности |
NavigationGraph | Композиция Route, Module, Scope и политик | Корень приложения |
NavigationSession | Стеки и объекты Flutter Router одного окна | Корневой StatefulWidget |
NavigationPort | Конкретные операции над стеком | Из BuildContext или через DI |
Что происходит после push
Ark Navigation:
- находит Route Definition для
ProductDestination; - определяет Module, Mount и Navigator Scope;
- применяет Redirect;
- проверяет Guard для выхода (
leave) и входа (enter); - фиксирует новый Snapshot одним изменением;
- передаёт страницы Flutter Router;
- завершает
ticket.committed; - завершает
ticket.completed, когда Product будет закрыт или удалён.
Защищённая страница не попадает в стек до завершения политик.
Где хранить Session
dart
final class AppHostState extends State<AppHost> {
late final NavigationSession navigation = NavigationSession(
id: const NavigationSessionId('main-window'),
graph: createAppGraph(),
);
@override
Widget build(BuildContext context) => MaterialApp.router(
routerConfig: navigation.routerConfig,
);
@override
void dispose() {
navigation.dispose();
super.dispose();
}
}
Не создавайте Session в build(): при перестроении потеряются ключи Navigator, история, стеки и ожидающие результата Ticket.
Зависимость Presenter или сервиса
Передайте NavigationPort, а не BuildContext:
dart
final class CheckoutPresenter {
CheckoutPresenter(this.navigation);
final NavigationPort navigation;
void showReceipt(String orderId) {
navigation.replaceTop<void>(ReceiptDestination(orderId));
}
}
Конкретный NavigationController нужен только инфраструктуре: восстановлению, диагностике и обновлению Graph.