Правильный способ обработки навигации с использованием BLoC

То, что вы пытаетесь сделать, звучит опасно, поскольку это не намеренное использование AUTO_INCREMENT.

Если вы действительно хотите найти наименьшее неиспользованное значение ключа, не используйте AUTO_INCREMENT и управлять своими ключами вручную.

Сделайте шаг назад и спросите «, почему вам нужно перерабатывать значения ключей? » Делать unsigned INT (или BIGINT) не обеспечивают достаточно большое пространство для ключей?

На самом деле вы будете иметь больше 18,446,744,073,709,551,615 уникальных записей за всю жизнь вашего приложения?

3
задан harisk92 13 July 2018 в 22:18
поделиться

1 ответ

Для обычной навигации, инициированной пользователем, вам вообще не нужен шаблон BLoC. Просто используйте Navigator.

Вход - это особый случай. Следуя шаблону BLoC, было бы целесообразно предоставить поток isAuthenticated:

abstract class MyBloc {
  Stream<bool> get isAuthenticated;
}

В вашем приложении, вероятно, будут два разных имени маршрута: один для зарегистрированных пользователей и один для анонимных пользователей:

final Map<String, WidgetBuilder> anonymousRoutes = {
  '/': (context) => new LoginScreen(), // default for anon
  '/register': (context) => new RegisterScreen(),
};

final Map<String, WidgetBuilder> authenticatedRoutes = {
  '/': (context) => new HomeScreen(), // default for logged in
  '/savings': (context) => new SavingsScreen(),
  // ...
};

Обычно Navigator и его именованные маршруты тесно связаны с MaterialApp, но вы также можете определить свой собственный, который перестраивается при обновлении потока isAuthenticated:

class MyApp extends StatelessWidget {
  const MyApp({Key key, this.bloc}) : super(key: key);

  final MyBloc bloc;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: (BuildContext context, Widget child) {
        return StreamBuilder<bool>(
          stream: bloc.isAuthenticated,
          builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
            if (!snapshot.hasData) {
              return Text('loading...');
            }

            bool isAuthenticated = snapshot.data;
            return _buildNavigator(isAuthenticated);
          },
        );
      },
    );
  }
}

Navigator _buildNavigator(bool isAuthenticated) {
  // different route tree and different default route depending on auth state
  final routes = isAuthenticated ? authenticatedRoutes : anonymousRoutes;

  return Navigator(
    key: new ValueKey(isAuthenticated),
    onGenerateRoute: (RouteSettings settings) {
      final name = settings.name;
      return new MaterialPageRoute(
        builder: routes[name],
        settings: settings,
      );
    },
    onUnknownRoute: (RouteSettings settings) {
      throw Exception('unknown route');
    },
  );
}

К сожалению, сейчас (2018-07-14) в коде флаттера есть два противоречивых утверждения , которые вы должны удалить, чтобы сделать код выше работы (вы может просто отредактировать его с вашей IDE):

Линия 93 и 96 в packages\flutter\lib\src\widgets\app.dart

//assert(navigatorObservers != null),
//assert(onGenerateRoute != null || navigatorObservers == const <NavigatorObserver>[]),
2
ответ дан boformer 17 August 2018 в 12:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: