gpt4 book ai didi

flutter - 如何在上下文之间共享 bloc

转载 作者:IT王子 更新时间:2023-10-29 06:57:39 26 4
gpt4 key购买 nike

在使用 showDialog() 导航到新上下文后,我试图访问在我的应用程序根附近创建的 bloc 实例.但是,如果我像往常一样尝试通过从 _thisBlocInstance = BlocProvider.of<ThisBlocType>(context) 这样的上下文中获取它来获取 bloc ,我收到一条错误消息,指示在此上下文中未提供任何 bloc。

我假设这是因为 showDialog() builder 方法为对话框中的小部件分配一个新的上下文,这些小部件不知道我正在尝试查找的 Bloc,它在用户登录后立即实例化:

  @override
Widget build(BuildContext context) {
_authBloc = BlocProvider.of<AuthBloc>(context);
_accountBloc = AccountBloc(authBloc: _authBloc);

return BlocProvider(
bloc: _accountBloc,

....

角落里有一个显示对话框的按钮:

@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.all(18.0),
child: FloatingActionButton(
onPressed: () => showDialog(
context: context,
builder: (newContext) => EventDialog(),
).then(
(val) => print(val)
),
child: Icon(Icons.add),
),
),
);
}

然后在 EventDialog 中,我尝试再次找到具有上下文的 bloc:

@override
void build(BuildContext context) {

_accountBloc = BlocProvider.of<AccountBloc>(context);
_userMenuItems = _accountBloc.usersInAccount
.map((user) => DropdownMenuItem(
child: Text(user.userName),
value: user.userId,
))
.toList();
}

这失败了,出现错误“getter bloc was called on null”,或者,没有该类型的 bloc 附加到此上下文。

在使用 showDialog() 之后,是否有某种方法可以仅从上下文访问 bloc,或者以其他方式导航到新的上下文?

这是 bloc 提供者类:

import 'package:flutter/material.dart';

//This class is a generic bloc provider from https://www.didierboelens.com/2018/08/reactive-programming---streams---bloc/
//it allows easy access to the blocs by ancestor widgets and handles calling their dispose method

class BlocProvider<T extends BlocBase> extends StatefulWidget {
BlocProvider({
Key key,
@required this.child,
@required this.bloc,
}): super(key: key);

final T bloc;
final Widget child;

@override
_BlocProviderState<T> createState() => _BlocProviderState<T>();

static T of<T extends BlocBase>(BuildContext context){
final type = _typeOf<BlocProvider<T>>();
BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
return provider.bloc;
}

static Type _typeOf<T>() => T;
}

class _BlocProviderState<T> extends State<BlocProvider<BlocBase>>{
@override
void dispose(){
widget.bloc.dispose();
super.dispose();
}

@override
Widget build(BuildContext context){
return widget.child;
}
}

abstract class BlocBase {
void dispose();
}

最佳答案

我发现在新上下文中访问原始 bloc 的最佳方法是将对它的引用传递给管理新上下文逻辑的新 bloc。为了保持代码模块化,每个 Bloc 不应控制超过一页的逻辑或一件事(例如,用户的登录状态)。因此,当我使用 showDialog() 创建一个新的屏幕/上下文时,我还应该有一个新的 block 来处理该屏幕中的逻辑。如果我需要对原始 bloc 的引用,我可以通过对话框小部件的构造函数将其传递给新 bloc 的构造函数,因此原始 bloc 中的任何信息仍然可以被新的 bloc/context 访问:

    child: FloatingActionButton(
onPressed: () => showDialog(
context: context,
builder: (newContext) => NewEventDialog(
accountBloc: BlocProvider.of<AccountBloc>(context),
),
).then((event) => eventsBloc.addEvent(event)),

...

class NewEventDialog extends StatelessWidget {
final AccountBloc accountBloc;
NewEventBloc _newEventBloc;

NewEventDialog({this.accountBloc}) : assert(accountBloc != null);

@override
Widget build(BuildContext context) {
_newEventBloc = NewEventBloc(accountBloc: accountBloc);

return BlocProvider(
bloc: _newEventBloc,
...

关于flutter - 如何在上下文之间共享 bloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55426229/

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