Могут ли Flutter Router Navigator и Provider на верхнем уровне работать вместе?

У меня большая проблема при использовании управления состоянием с Провайдерами и навигатором.

Что мы должны знать:

1) Мой RESTFUL API дает токен, срок действия которого истекает через 12 часов.

2) My home: параметр обусловлен, если пользователь аутентифицирован или нет ... если нет, на основе других параметров я должен решить, какой экран должен быть домашним.

3) Если я нахожусь на одном экране и токен истекает при ЛЮБОМ запросе, который приложение выполняет с API, я:

  • Вызов функции внутри моего auth провайдера, который выполняет процедуры выхода (я очищаю localStorage с помощью токена). Этот auth провайдер устанавливает для свойства isAuth значение false.
  • Когда isAuth ложно, если вы посмотрите main.dart файл на home:, вы увидите, что будет отображаться LoginPage().

Здесь все хорошо. Проблема в том, что я должен выполнить перенаправление с использованием Navigator.of... .. Если, например, в случае ошибки токена истек, я делаю: Navigator.popUntil(context, ModalRoute.withName('/login')); приложение переходит на LoginPage() без проблем, но ... когда я пытаюсь использовать логин (используя функцию login провайдера auth) он остается на странице входа! Если я использую в любом месте Navigator для перехода в любое другое место, похоже, что он переопределяет «способ управления состоянием», который я использую для управления тем, какая страница отображается как home.

Не могли бы вы мне помочь?

Мой main.dart код:

// Providers
import 'package:provider/provider.dart';
import 'package:cadsanjuan_movil/providers/auth.dart';

// Pages
import './pages/login_page.dart';
import './pages/initial_loading_page.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  final storage = new FlutterSecureStorage();
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider<Auth>(create: (context) => Auth()),
          ChangeNotifierProvider<TurnActive>(create: (context) => TurnActive()),
          ChangeNotifierProxyProvider<TurnActive, Checkup>(
              create: (context) => Checkup(),
              update: (_, turnActive, checkup) {
                checkup.turnData = turnActive.turnData;
                return checkup;
              }),
          ChangeNotifierProxyProvider<Auth, ErrorProvider>(
              create: (context) => ErrorProvider(),
              update: (_, auth, errorProvider) {
                errorProvider.logoff = auth.logoff;
                return errorProvider;
              }),
        ],
        child: Consumer3<Auth, TurnActive, Checkup>(
          builder: (context, auth, turnActive, checkup, _) {
            return MaterialApp(
              title: 'CAD App',
              theme: ThemeData(
                primarySwatch: Colors.blue,
              ),
              home: auth.isAuth
                  ? (turnActive.turnData != null &&
                          turnActive.turnData['turn']['checkUpStartId'] != null)
                      ? CheckupPage() // Si el cotejo está en proceso
                      : InitialLoadingPage() // Si no hay cotejo iniciado
                  : FutureBuilder(
                      // Si estamos no hay autenticación en el estado, se chequea en el localStorage
                      future: auth.tryAutoLogin(),
                      builder: (ctx, authResultSnapshot) =>
                          authResultSnapshot.connectionState ==
                                  ConnectionState.waiting
                              ? LoadingData()
                              : LoginPage(),
                    ),
              routes: {
                LoginPage.routeName: (context) => LoginPage(),
                InitialLoadingPage.routeName: (context) => InitialLoadingPage(),
                CheckupPage.routeName: (context) => CheckupPage(),
                CheckupGroupsPage.routeName: (context) => CheckupGroupsPage(),
              },
            );
          },
        ));
  }
}

person Ali Briceño    schedule 10.02.2020    source источник
comment
Это помогает? stackoverflow.com/a/60121967/7034640   -  person Ted Henry    schedule 10.02.2020
comment
= / не совсем мой друг ...   -  person Ali Briceño    schedule 10.02.2020


Ответы (1)


Проблема заключалась в следующем:

Navigator.popUntil(context, ModalRoute.withName('/login'))

Если мы нажмем «/ login», это переопределит параметр home в MaterialApp, загрузится страница входа в систему, но страница не появится из-за маршрута. Правильный способ сделать это:

Navigator.of(context)
          .pushNamedAndRemoveUntil('/', (Route<dynamic> route) => false);

С этим мы перенаправляем на '/', и тогда управление состоянием с использованием домашнего параметра будет работать.

person Ali Briceño    schedule 14.02.2020