gpt4 book ai didi

flutter - 使用 flutter_bloc 构建 Flutter App 的架构

转载 作者:行者123 更新时间:2023-12-03 03:24:08 24 4
gpt4 key购买 nike

我必须用 Flutter 开发一个简单的应用程序,我第一次尝试使用 bloc 模式。我正在使用 flutter_bloc包,但我有两个主要问题并且卡住了:

  • 应用程序中的所有屏幕都有 block ,这些 block 依赖于 repos 向服务器发出请求,并且对于每个请求,我都需要一个 token 。我在 authentication_bloc 获得 token (登录),但我不能将该 token 共享给所有集团,除非我让它们依赖于 auth_bloc(拥有存储 token 的用户模型的集团)。对于一个简单的应用程序,也许它可以工作,但如果其他 bloc 除了 auth_bloc 之外还有更多 bloc 依赖项,那么将所有 bloc 作为依赖项注入(inject)可能会变得一团糟。什么替代方案可能是一个好的解决方案?
  • 对于导航,我有一个 bloc用于底部导航栏。但是我想所有的标签页上的屏幕都可以调用change_tab()功能在底部栏 block 。同样是同样的问题,如果其他集团对底栏集团有依赖关系,我只能在底栏集团添加事件。我不想将身份验证 block 和底栏 block 添加为对管理所有屏幕的所有 block 的依赖项。

  • 我感谢建议、替代方案或文档,我可以学习为应用程序构建一个比示例显示的更复杂的良好架构 here

    最佳答案

    您可以将 token 存储在 RepositoryuserRepository.persistToken(event.token)await userRepository.deleteToken();存储库的行为类似于存储库模式。您不需要知道数据来自云或本地数据库
    在下面的示例中,userRepository 可以是应用程序级别,因此所有 bloc 都可以使用它
    完整示例代码 https://github.com/felangel/bloc/blob/master/examples/flutter_login/lib/authentication/authentication_bloc.dart
    代码片段

    void main() {
    BlocSupervisor.delegate = SimpleBlocDelegate();
    final userRepository = UserRepository();
    runApp(
    BlocProvider<AuthenticationBloc>(
    create: (context) {
    return AuthenticationBloc(userRepository: userRepository)
    ..add(AppStarted());
    },
    child: App(userRepository: userRepository),
    ),
    );
    }

    ...

    import 'package:meta/meta.dart';
    import 'package:bloc/bloc.dart';
    import 'package:user_repository/user_repository.dart';

    import 'package:flutter_login/authentication/authentication.dart';

    class AuthenticationBloc
    extends Bloc<AuthenticationEvent, AuthenticationState> {
    final UserRepository userRepository;

    AuthenticationBloc({@required this.userRepository})
    : assert(userRepository != null);

    @override
    AuthenticationState get initialState => AuthenticationUninitialized();

    @override
    Stream<AuthenticationState> mapEventToState(
    AuthenticationEvent event,
    ) async* {
    if (event is AppStarted) {
    final bool hasToken = await userRepository.hasToken();

    if (hasToken) {
    yield AuthenticationAuthenticated();
    } else {
    yield AuthenticationUnauthenticated();
    }
    }

    if (event is LoggedIn) {
    yield AuthenticationLoading();
    await userRepository.persistToken(event.token);
    yield AuthenticationAuthenticated();
    }

    if (event is LoggedOut) {
    yield AuthenticationLoading();
    await userRepository.deleteToken();
    yield AuthenticationUnauthenticated();
    }
    }
    }

    您可以使用 MultiBlocProvider在应用程序级别包装你的 block
    下面的例子是 map 和位置
    https://gitlab.kaleidos.net/piweek/betover/betover-mobile/blob/7b9368288743be602f37014f7a49ed4ef943afc1/lib/main.dart
    void main() {
    BlocSupervisor.delegate = SimpleBlocDelegate();

    runApp(
    MultiBlocProvider(
    providers: [
    BlocProvider<MapBloc>(
    create: (context) => MapBloc(),
    ),
    BlocProvider<PoisBloc>(
    create: (context) => PoisBloc(
    mapBloc: BlocProvider.of<MapBloc>(context),
    ),
    ),
    ],
    child: App(),
    )
    );
    }

    class App extends StatelessWidget {
    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    title: 'Bet Over',
    theme: appTheme,
    initialRoute: '/',
    routes: {
    '/': (context) =>
    MultiBlocProvider(
    providers: [
    BlocProvider<MapBloc>(
    create: (context) => BlocProvider.of<MapBloc>(context),
    ),
    BlocProvider<PoisBloc>(
    create: (context) => BlocProvider.of<PoisBloc>(context),
    ),
    ],
    child: MapPage(),
    ),
    '/create-poi': (context) =>
    MultiBlocProvider(
    providers: [
    BlocProvider<MapBloc>(
    create: (context) => BlocProvider.of<MapBloc>(context),
    ),
    BlocProvider<PoisBloc>(
    create: (context) => BlocProvider.of<PoisBloc>(context),
    ),
    ],
    child: CreatePoimPage(),
    ),
    }
    );
    }
    }

    并使用它 https://gitlab.kaleidos.net/piweek/betover/betover-mobile/blob/7b9368288743be602f37014f7a49ed4ef943afc1/lib/ui/widgets/map.dart
    class _MapState extends State<Map> {
    MapBloc _mapBloc;
    PoisBloc _poisBloc;


    @override
    void initState() {
    super.initState();

    _mapBloc = BlocProvider.of<MapBloc>(context);
    _poisBloc = BlocProvider.of<PoisBloc>(context);

    ...
    List<Marker> _generateMarkers () {
    if (!(_mapBloc.state is MapViewboxChanged && _poisBloc.state is PoisLoaded))
    return [];

    关于flutter - 使用 flutter_bloc 构建 Flutter App 的架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59621809/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com