Flutter 再次触发 bloc 事件

Posted

技术标签:

【中文标题】Flutter 再次触发 bloc 事件【英文标题】:Flutter Trigger bloc event again 【发布时间】:2022-01-01 19:02:59 【问题描述】:

在我的第一个屏幕上,我填写了表格,然后单击下一步按钮,它将 SubmitDataEvent() 添加到该集团。然后,BolcListner 列表和 SuccessSate 导航到下一个屏幕。

在第二个屏幕上,当我单击后退按钮时,它会导航到上一个屏幕。之后,当我更改表单上的用户输入数据并再次单击下一步按钮时,现在 SubmitDataEvent() 没有添加。

我更喜欢一些与此相关的资源,我理解问题是状态位于SuccessSate 并且不会更改为InitialState。所以在dispose()我用bloc.close();

@override
  void dispose() 
    bloc.close();
    super.dispose();
  

但是,它仍然无法正常工作。另外,我尝试使用此代码

@override
  void dispose() 
    bloc.emit(InitialState);
    bloc.close();
    super.dispose();
  

还是不行。

我用它在屏幕之间导航:

Navigator.popAndPushNamed()

我想做的是: 在第一个屏幕上,当单击下一个按钮 SubmitDataEvent() 添加到该集团,它在SuccessState 它导航到下一个屏幕。当我单击第二页上的后退按钮时,它会再次导航到第一个屏幕。现在,当我单击第一个屏幕上的下一步按钮时 我想再次运行所有 bloc 进程。 第一个和第二个屏幕没有依赖关系。

首屏代码:

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

    bloc = injection<SubmitPersonalDetailsBloc>();

    EasyLoading.addStatusCallback((status) 
      print('EasyLoading Status $status');
      if (status == EasyLoadingStatus.dismiss) 
        _timer?.cancel();
      
    );
  

 @override
  void dispose() 
    _scrollController.dispose();
    bloc.close();
    super.dispose();
  
 @override
  Widget buildView(BuildContext context) 
    return Scaffold(
      body: BlocProvider<SubmitPersonalDetailsBloc>(
        create: (_) => bloc,
        child: BlocListener<SubmitPersonalDetailsBloc,
            BaseState<PersonalDetailsState>>(
          listener: (context, state) 
            if (state is LoadingSubmitPersonalDetailsState) 
              EasyLoading.show(status: 'Submitting Data');
            
            if (state is SubmitPersonalDetailsSuccessState) 
              setState(() 
                submitPersonalDetailsResponseEntity =
                    state.submitPersonalDetailsResponseEntity;
              );
              if (submitPersonalDetailsResponseEntity!.responseCode == "00") 
                EasyLoading.showSuccess('Done!');
                //Navigate next screen
                EasyLoading.dismiss();
              
             else if (state is SubmitPersonalDetailsFailedState) 
              EasyLoading.showError(state.error);            
          ,
....

【问题讨论】:

你在哪里创建你的集团? 拜托,分享块代码sn-p。 我在页面顶部使用了 bloc provider 尝试使用 Navigator.pushNamed() 或 Navigator.pushReplacementNamed() 进行导航 @Poran 我添加了代码 【参考方案1】:

你可以试试这个sn-p

 if (result.responseCode == APIResponse.RESPONSE_SUCCESS) 
                  yield SubmitPersonalDetailsSuccessState(
                      submitPersonalDetailsResponseEntity: r);
                 else
                    yield SubmitPersonalDetailsFailedState(error: r.responseMsg);
                

【讨论】:

还是不行【参考方案2】:

问题在于依赖注入,一旦它创建了一个实例,参数就不会改变。因此,当导航到下一个屏幕时,必须重置该实例。

@override
  void dispose() 
    _scrollController.dispose();
    bloc.close();
    injection.resetLazySingleton<SubmitPersonalDetailsBloc>(); // here reset the instance
    super.dispose();
  

【讨论】:

以上是关于Flutter 再次触发 bloc 事件的主要内容,如果未能解决你的问题,请参考以下文章

Flutter BLoC mapEventToState 仅在事件的第一次调用时才被调用,并且不会在下次触发该事件时调用

一旦使用 bloc 触发事件,底页就会重复显示

Flutter 从其他 Bloc 监听 Bloc 状态

Flutter Bloc 冲突状态

Flutter Bloc 如何从 Widget 本身更新 BlocBuilder 中的 Widget?

Flutter bloc 在 7.2.0 版本中没有用 Equatable 重建