Flutter BLoC 架构 - 角色

Flutter BLoC Architecture - Role(s)

这是一个主要关于最佳实践的问题,我是 flutter dev 和 BLoC 架构的新手,总而言之,我有一个 app_bloc 处理用户身份验证(firebase 登录)的应用程序,很简单,有两个状态 Authenticated 和 Unauthenticated。

我的应用根据用户是否通过身份验证来呈现页面,无论是登录页面还是主页。

import 'package:authentication_repository/authentication_repository.dart';
import 'package:flow_builder/flow_builder.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:majstor/app/bloc/app_bloc.dart';
import 'package:majstor/app/routes/routes.dart';
import 'package:majstor/theme.dart';

class App extends StatelessWidget {
  const App({
    Key? key,
    required AuthenticationRepository authenticationRepository,
  })  : _authenticationRepository = authenticationRepository,
        super(key: key);

  final AuthenticationRepository _authenticationRepository;

  @override
  Widget build(BuildContext context) {
    return RepositoryProvider.value(
      value: _authenticationRepository,
      child: BlocProvider(
        create: (_) => AppBloc(
          authenticationRepository: _authenticationRepository,
        ),
        child: const AppView(),
      ),
    );
  }
}

class AppView extends StatelessWidget {
  const AppView({Key? key}) : super(key: key);



  @override
  Widget build(BuildContext context) {
/// try context.select here maybe?
    return MaterialApp(
      home: FlowBuilder<AppStatus>(
        state: context.select((AppBloc bloc) => bloc.state.status),
        onGeneratePages: onGenerateAppViewPages,
      ),
    );
  }
}
import 'package:flutter/widgets.dart';
import 'package:majstor/app/app.dart';
import 'package:majstor/home/home.dart';
import 'package:majstor/login/login.dart';

List<Page> onGenerateAppViewPages(AppStatus state, List<Page<dynamic>> pages) {
  switch (state) {
    case AppStatus.authenticated:
      return [HomePage.page()];
    case AppStatus.unauthenticated:
    default:
      return [LoginPage.page()];
  }
}

现在我很难理解的是,在我的主页案例中,我想进一步 'split' 我的用户进入角色,将有两个角色存储在一个 Firebase 集合,在同一文档上具有用户的相应 ID,并且应该为每个角色构建一个完全不同的页面,我不确定我到底应该在哪里进行这个角色检查,从技术上讲,我可以在下面的主页中查询通过使用用户 ID 和获取角色的数据库,然后与我对登录名和主页所做的类似,使用 flowbuilder 根据角色生成不同的页面?但这是一个好习惯吗?我有点觉得我应该在别处分离数据库逻辑,但由于我是这种开发的新手,我不知道我应该在哪里做这个来构建一个可扩展的应用程序。

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:majstor/app/app.dart';
import 'package:majstor/home/home.dart';
import 'package:majstor/utils/databaseservice.dart';

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  static Page page() => const MaterialPage<void>(child: HomePage());

  @override
  Widget build(BuildContext context) {
    final textTheme = Theme.of(context).textTheme;
    final user = context.select((AppBloc bloc) => bloc.state.user);
    Database db = Database();
    db.readData(user.id);

    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
        actions: <Widget>[
          IconButton(
            key: const Key('homePage_logout_iconButton'),
            icon: const Icon(Icons.exit_to_app),
            onPressed: () => context.read<AppBloc>().add(AppLogoutRequested()),
          )
        ],
      ),
      body: Align(
        alignment: const Alignment(0, -1 / 3),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Avatar(photo: user.photo),
            const SizedBox(height: 4),
            Text(user.email ?? '', style: textTheme.headline6),
            const SizedBox(height: 4),
            Text(user.name ?? '', style: textTheme.headline5),
          ],
        ),
      ),
    );
  }
}

我是在上面的文件中查询数据库,并在那里进行检查,还是有办法进一步分离我的逻辑?我是否也应该使用 BloC 作为角色?还是我应该以某种方式将角色整合到我现有的 BloC 中?希望我的解释足够清楚。

所以我不是 Flutter 开发人员,但我可以根据我的一般经验和针对您的问题所做的一些研究提供一些建议。我假设您对 Bloc 对齐的概念与 this.

有点相似

I'd like to further 'split' my users into roles ... I'm not sure where exactly would I do this role check

  • 我会制作一个代表用户身份验证和授权状态的 Bloc(逻辑 class),为了便于讨论,我们将其称为 UserAuthBloc。
  • 当您的其他 Bloc 去做事情时,只要他们需要根据用户身份验证状态或角色做出决定,他们就可以参考 UserAuthBloc。
  • 使用 BlocProvider 实现依赖注入通常是明智的,您也可以使用它向需要根据用户身份验证状态和角色成员资格做出决定的小部件提供 UserAuthBloc。

Do I query the database in the file above, and do the checks there or, is there a way to sort of separate my logic further? Should I be using BloCs for roles as well?

  • 查询用户身份验证和授权(角色)的数据库应该专门通过 UserAuthBloc 完成。
  • 检查是在 Bloc 级别完成的,至少尽可能多。如果您在 UI 中进行检查,请尝试将它们限制为可重复使用的小部件,以便在您需要进行更改时更改更少的代码。
  • 在大多数情况下,将身份验证和授权(角色)保持在同一个 Bloc 中对我来说很有意义,因为角色取决于被身份验证的用户。