Руководства

Установка функциональности во время работы

Приложение без Reports, транзакционная установка Module и Mount, переход и явная политика удаления активного Entry.

v1.1.0Продвинутый уровень

Установка функциональности во время работы

Динамическое изменение Graph нужно плагинам, загружаемым инструментам и функциям, которые доступны не во всех конфигурациях приложения. Для обычного перехода между страницами используйте NavigationPort.

Приложение запускается с Home. Кнопка Установить Reports добавляет Module и открывает Reports. Кнопка Удалить проверяет, что делать с активным Reports Entry.

01

Создайте Runtime и Session

dart
late final NavigationRuntime runtime = NavigationRuntime(graph: baseGraph());
late final NavigationSession session = runtime.createSession(
  id: const NavigationSessionId('dynamic-example'),
);

Runtime владеет текущей версией общего Graph, а Session — стеком одного окна.

02

Определите Reports Module

dart
final class ReportsDestination extends NavigationDestination<void> {
  const ReportsDestination();
}

NavigationModule reportsModule() => NavigationModule(
  id: const NavigationModuleId('reports'),
  routes: <NavigationRouteDefinitionBase>[
    NavigationRouteDefinition<ReportsDestination, void>(
      id: const NavigationRouteId('reports'),
      pageBuilder: (context, destination, entry) => const ReportsPage(),
      uriCodec: CallbackNavigationUriCodec<ReportsDestination>(
        pattern: '/',
        encoder: (destination) => Uri(path: '/'),
        decoder: (match) => const ReportsDestination(),
      ),
    ),
  ],
);

До установки Destination не может разрешиться в Graph.

03

Установите Module и Mount

dart
final results = await runtime.updateGraph(
  (builder) {
    final module = reportsModule();
    builder.installModule(module);
    builder.mount(NavigationMount(
      id: const NavigationMountId('reports-root'),
      moduleId: module.id,
      scopeId: const NavigationScopeId('root'),
      pathPrefix: '/reports',
    ));
  },
  activeEntries: const RejectActiveNavigationEntries(),
);

if (results[session.id]?.isCommitted ?? false) {
  session.controller.push<void>(const ReportsDestination());
}

Сначала проверяется весь новый Graph. Только после успешной проверки каждая Session переключается на него. Результат нужно проверить отдельно для каждой Session.

04

Выберите поведение при удалении

RejectActiveNavigationEntries отменяет обновление, если Reports открыт. RemoveActiveNavigationEntries удаляет затронутые Entry из стеков. MigrateActiveNavigationEntries заменяет их совместимыми Destination и сохраняет корректные типы результатов.