Flutter BLoC 架构 - 角色

Posted

技术标签:

【中文标题】Flutter BLoC 架构 - 角色【英文标题】:Flutter BLoC Architecture - Role(s) 【发布时间】:2021-11-02 18:17:43 【问题描述】:

这是一个主要关于最佳实践的问题,我是 Flutter 开发和 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()];
  

现在我很难理解的是,在我的主页案例中,我想进一步将我的用户“拆分”为角色,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 中?希望我的解释足够清楚。

【问题讨论】:

【参考方案1】:

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

我想进一步将我的用户“拆分”为角色...我不确定在哪里 我到底会不会做这个角色检查

我将创建一个表示用户身份验证和授权状态的 Bloc(逻辑类),为了便于讨论,我们将其称为 UserAuthBloc。 当您的其他 Bloc 进行工作时,他们可以在需要根据用户身份验证状态或角色做出决定时参考 UserAuthBloc。 使用 BlocProvider 实现依赖注入通常是明智的,您也可以使用它为需要根据用户身份验证状态和角色成员身份做出决策的小部件提供 UserAuthBloc。

我是否在上面的文件中查询数据库,并在那里进行检查,或者, 有没有办法进一步分离我的逻辑?我应该使用 BloC 也适用于角色?

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

【讨论】:

谢谢大佬,这个答案非常详细和深思熟虑,我会尽力做到这一点! 祝你好运!我也真的需要自己动手构建它。

以上是关于Flutter BLoC 架构 - 角色的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:我可以在 BLoC 架构中使用 setState() 吗?

如何在 Flutter 上实现 BLoC 模式的 TDD

flutter_bloc - 每个 Bloc 有多个存储库,还是只有一个?

Flutter 多个 Bloc 和 NamedRoutes

Flutter BLOC 和 Provider 如何注册在一起

Flutter 使用流“RxDart”提交登录 Bloc