Flutter:如何在控制器中触发 bloc 事件?
Flutter: How to trigger a bloc event in the controller?
总而言之,我希望“context.read().add(EnabledEvent())”从控制器本身或我可以用来从控制器触发事件并更新状态的其他替代方案工作:
class SplashCtrl extends GetxController {
@override
void onReady() {
User user = loadUser();
if (user.isExampleEnabled) {
context.read<ExampleBloc>().add(EnabledEvent());
}
}
我尝试的另一件事是:
ExampleBloc testBloc = ExampleBloc();
testBloc.add(TestEvent());
在控制器中,它似乎确实触发了事件,但 UI 不会随着状态变化而更新。我似乎真的需要 Context 来改变它。有什么想法吗?
更多细节和背景:
我不仅要在页面本身触发 bloc 事件,还要在页面的控制器中触发!
所以我的 flutter 应用程序中有一些页面,每个视图都有一个这样设置的控制器:
class SplashPage extends GetView<SplashCtrl> {
@override
Widget build(BuildContext context) {
Get.lazyPut(() => SplashCtrl());
return Scaffold(...);
}
}
SplashCtrl 是此页面的控制器。这个启动视图页面是第一个加载它的页面之一,当它被添加并准备好时(基本上是立即)运行功能,例如检查用户是否登录并将他们的数据加载到应用程序,如下所示:
class SplashCtrl extends GetxController {
@override
void onReady() {
// run stuff here
}
我已经能够在页面中创建 lambda 函数并根据它们的作用触发事件并像这样切换:
IconSwitchedButtonUi(
value: state.isExampleOn,
icon: Images.toggleIcon,
title: "Is Example enabled?",
onChanged: (value) {
if (value) {
context.read<ExampleBloc>().add(EnabledEvent());
} else {
context.read<ExampleBloc>().add(DisabledEvent());
}
},
),
但现在我需要一个 bloc 事件来触发并稍微更改状态,如果用户对他们的字段之一具有特定值。我怎么做?如何从控制器中触发事件? “context.read”不起作用,因为控制器没有上下文,或者有?
ExampleBloc testBloc = ExampleBloc(); testBloc.add(TestEvent());
这是行不通的,因为你正在声明一个全新的 bloc 实例,它没有通过任何 BlocProvider
连接到你的小部件树,因此你无法触发 this 会发出状态的集团事件 BlocBuilder
可以做出反应。由于没有提供给小部件树的 bloc read()
找不到这个 bloc。
为了完成这项工作,您需要:
Pass BuildContext
有 BlocProvider
提供的一些 Bloc 或 Cubit
void foo(BuildContext context) {
User user = loadUser();
if (user.isExampleEnabled) {
context.read<ExampleBloc>().add(EnabledEvent());
}
}
..或者直接在控制器内部监听 bloc 变化
class SplashCtrl extends GetxController {
SplashCtrl(MyBloc bloc) {
bloc.stream.listen((event) {
// React to bloc changes here
if (event is MyBlocEvent) {
// Do something
}
}
}
}
请记住,即使在这种方法中,给予 SplashCrtl
构造函数 的 bloc 实例也必须与 BlocProvider
按顺序提供给小部件树的 相同为了这个工作。
我能够通过向我的控制器添加一个延迟的 BuildContext 来解决这个问题:
class SplashCtrl extends GetxController {
late BuildContext context;
@override
void onReady() {
// run stuff here
}
之后,在页面本身中,我像这样传递上下文:
class SplashPage extends GetView<SplashCtrl> {
@override
Widget build(BuildContext context) {
controller.context = context;
Get.lazyPut(() => SplashCtrl());
return Scaffold(...);
}
}
然后我就可以在控制器内部使用上下文了!!
if (value) {
context.read<ExampleBloc>().add(EnabledEvent());
} else {
context.read<ExampleBloc>().add(DisabledEvent());
}
},
总而言之,我希望“context.read().add(EnabledEvent())”从控制器本身或我可以用来从控制器触发事件并更新状态的其他替代方案工作:
class SplashCtrl extends GetxController {
@override
void onReady() {
User user = loadUser();
if (user.isExampleEnabled) {
context.read<ExampleBloc>().add(EnabledEvent());
}
}
我尝试的另一件事是:
ExampleBloc testBloc = ExampleBloc();
testBloc.add(TestEvent());
在控制器中,它似乎确实触发了事件,但 UI 不会随着状态变化而更新。我似乎真的需要 Context 来改变它。有什么想法吗?
更多细节和背景:
我不仅要在页面本身触发 bloc 事件,还要在页面的控制器中触发!
所以我的 flutter 应用程序中有一些页面,每个视图都有一个这样设置的控制器:
class SplashPage extends GetView<SplashCtrl> {
@override
Widget build(BuildContext context) {
Get.lazyPut(() => SplashCtrl());
return Scaffold(...);
}
}
SplashCtrl 是此页面的控制器。这个启动视图页面是第一个加载它的页面之一,当它被添加并准备好时(基本上是立即)运行功能,例如检查用户是否登录并将他们的数据加载到应用程序,如下所示:
class SplashCtrl extends GetxController {
@override
void onReady() {
// run stuff here
}
我已经能够在页面中创建 lambda 函数并根据它们的作用触发事件并像这样切换:
IconSwitchedButtonUi(
value: state.isExampleOn,
icon: Images.toggleIcon,
title: "Is Example enabled?",
onChanged: (value) {
if (value) {
context.read<ExampleBloc>().add(EnabledEvent());
} else {
context.read<ExampleBloc>().add(DisabledEvent());
}
},
),
但现在我需要一个 bloc 事件来触发并稍微更改状态,如果用户对他们的字段之一具有特定值。我怎么做?如何从控制器中触发事件? “context.read”不起作用,因为控制器没有上下文,或者有?
ExampleBloc testBloc = ExampleBloc(); testBloc.add(TestEvent());
这是行不通的,因为你正在声明一个全新的 bloc 实例,它没有通过任何 BlocProvider
连接到你的小部件树,因此你无法触发 this 会发出状态的集团事件 BlocBuilder
可以做出反应。由于没有提供给小部件树的 bloc read()
找不到这个 bloc。
为了完成这项工作,您需要:
Pass BuildContext
有 BlocProvider
提供的一些 Bloc 或 Cubit
void foo(BuildContext context) {
User user = loadUser();
if (user.isExampleEnabled) {
context.read<ExampleBloc>().add(EnabledEvent());
}
}
..或者直接在控制器内部监听 bloc 变化
class SplashCtrl extends GetxController {
SplashCtrl(MyBloc bloc) {
bloc.stream.listen((event) {
// React to bloc changes here
if (event is MyBlocEvent) {
// Do something
}
}
}
}
请记住,即使在这种方法中,给予 SplashCrtl
构造函数 的 bloc 实例也必须与 BlocProvider
按顺序提供给小部件树的 相同为了这个工作。
我能够通过向我的控制器添加一个延迟的 BuildContext 来解决这个问题:
class SplashCtrl extends GetxController {
late BuildContext context;
@override
void onReady() {
// run stuff here
}
之后,在页面本身中,我像这样传递上下文:
class SplashPage extends GetView<SplashCtrl> {
@override
Widget build(BuildContext context) {
controller.context = context;
Get.lazyPut(() => SplashCtrl());
return Scaffold(...);
}
}
然后我就可以在控制器内部使用上下文了!!
if (value) {
context.read<ExampleBloc>().add(EnabledEvent());
} else {
context.read<ExampleBloc>().add(DisabledEvent());
}
},