【问题标题】:Flutter Bloc - Flutter Bloc state not updatingFlutter Bloc - Flutter Bloc 状态未更新
【发布时间】:2021-03-19 05:30:32
【问题描述】:

我刚刚开始使用颤振集团。 我尝试制作状态,但它总是进入初始状态。有什么解决办法?

集团

class VisiMisiBloc extends Bloc<VisiMisiEvent, VisiMisiState> {
  VisiMisiBloc(this.visiMisiRepository) : super(VisiMisiInitial());

  final VisiMisiRepository visiMisiRepository;
  
  @override
  Stream<VisiMisiState> mapEventToState(VisiMisiEvent event) async* {
    if (event is GetVisiMisiList) {
      yield* _getVisiMisi(event, state);
    }
  }

  Stream<VisiMisiState> _getVisiMisi(VisiMisiEvent event, VisiMisiState state) async* {
    yield VisiMisiLoading();
    try {
      ResponseModel<VisiMisiModel> response = await visiMisiRepository.getVisiMisi();
      print(response);

      if (response.statusCode == 0) {
        int insertedId = await visiMisiRepository.insertVisiMisi(response.data);
        print(insertedId);
        List<VisiMisiModel> visiMisiList = await visiMisiRepository.getAllVisiMisi();
        yield VisiMisiLoaded(visiMisiList);

      } else {
        yield VisiMisiError(response.errorMessage);
      }
    } on Exception catch (e) {
      yield VisiMisiError(e.toString());
    }
  }
}

状态

part of 'visi_misi_bloc.dart';

abstract class VisiMisiState extends Equatable {
  const VisiMisiState();
}

class VisiMisiInitial extends VisiMisiState {
  const VisiMisiInitial();
  @override
  List<Object>get props => [];
}


class VisiMisiLoading extends VisiMisiState {
  const VisiMisiLoading();
  @override
  List<Object>get props => [];
}

class VisiMisiLoaded extends VisiMisiState {
  final List<VisiMisiModel> visiMisiModel;
  const VisiMisiLoaded(this.visiMisiModel);
  @override
  List<Object> get props => [visiMisiModel];
}

class VisiMisiError extends VisiMisiState {
  final String message;
  const VisiMisiError(this.message);
  @override
  List<Object>get props => [message];
}

活动

part of 'visi_misi_bloc.dart';

abstract class VisiMisiEvent extends Equatable{
  const VisiMisiEvent();
}

class GetVisiMisiList extends VisiMisiEvent {
  @override
  List<Object> get props => [];
}

存储库

abstract class VisiMisiRepository {
  Future<int> insertVisiMisi(VisiMisiModel todo);
  Future<ResponseModel<VisiMisiModel>> getVisiMisi();
  Future<List<VisiMisiModel>> getAllVisiMisi();
}

存储库实现

class VisiMisiRepositoryImpl extends VisiMisiRepository {
  final NetworkInfoImpl networkInfo;
  final RemoteDataSource remoteDatasource;
  final VisiMisiDao dao;

  VisiMisiRepositoryImpl(this.networkInfo, this.remoteDatasource, this.dao);

  @override
  Future<ResponseModel<VisiMisiModel>> getVisiMisi() {
    return remoteDatasource.visiMisi();
  }

  @override
  Future<int> insertVisiMisi(VisiMisiModel todo) {
    return dao.upsert(todo);
  }

  @override
  Future<List<VisiMisiModel>> getAllVisiMisi() {
    return dao.getAll(userTABLE, VisiMisiModel.fromJson);
  }
}

远程数据源

Future<ResponseModel<VisiMisiModel>> visiMisi() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String auth_token = prefs.getString("auth_token");
    try {
      final response = await httpClient.get(ServiceUrl.visiMisi, auth_token);

      if(response.statusCode != 200){
        throw new Exception('Error getting visi misi');
      }

      return ResponseModel<VisiMisiModel>.fromJson(response, VisiMisiModel.fromJson);
    }catch(e){
      print(e);
    }
  }

查看

class VisiMisiPage extends StatefulWidget {
  @override
  _VisiMisiPageState createState() => _VisiMisiPageState();
}

class _VisiMisiPageState extends State<VisiMisiPage> {
  VisiMisiRepository repository;

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

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          backgroundColor: AppColor.white,
          appBar: AppBar(
            title: Text("VISI & MISI", style: TextStyle(fontSize: 16, color: AppColor.deepCerulean),),
            backgroundColor: Colors.white,
            elevation: 0,
            automaticallyImplyLeading: false,
            brightness: Brightness.light,
            leading: IconButton(
              icon: new Icon(Icons.arrow_back, color: AppColor.deepCerulean,),
              onPressed: () => Navigator.of(context).pop(),
            ),
          ),
          body: BlocProvider<VisiMisiBloc>(
            create: (_) => VisiMisiBloc(repository),
            child: BlocBuilder<VisiMisiBloc, VisiMisiState>(
                  builder: (context, state) {
                    if (state is VisiMisiInitial) {
                      //BlocProvider.of<VisiMisiBloc>(context).add(GetVisiMisiList());
                      return Center(child: Text(state.toString()),);
                    } else if (state is VisiMisiLoading) {
                      return Center(child: CircularProgressIndicator(),);
                    } else if (state is VisiMisiLoaded) {
                      return SingleChildScrollView(
                        child: Container(
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              _visiWidget(context, state),
                              SizedBox(height: 20,),
                              _misiWidget(context),
                              SizedBox(height: 30,),
                              _footerWidget(context)
                            ],
                          ),
                        ),
                      );
                    } else if (state is VisiMisiError) {
                      return Center(child: Text(state.message),);
                    }
                  }
              )
            ),
          )
    );
  }

  void _onWidgetDidBuild(Function callback) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      callback();
    });
  }
}

我得到一个未处理的异常:未处理的错误 NoSuchMethodError:方法 'getVisiMisi' 在 null 上被调用。

在视图中,状态显示在 VisiMisiInitial 中,并且不想更新到 VisiMisiLoading

【问题讨论】:

    标签: flutter dart state bloc


    【解决方案1】:

    我分析了你的代码,发现了2个错误:

    1st.您刚刚创建了 VisiMisiRepository 的实例,但尚未初始化。你正在调用他们的方法,这就是为什么你会收到错误Unhandled error NoSuchMethodError: The method 'getVisiMisi' was called on null.

    第二次。您刚刚在传递的存储库实例中初始化了您的 bloc,并且还没有执行任何 bloc 事件。这就是代码一直显示初始状态的原因。

    您可能已经得到了答案。 如果没有,请从这里寻求帮助,它一定会对您有所帮助:

    替换这个:

    create: (_) =&gt; VisiMisiBloc(repository),

    用这个:

    create: (_) =&gt; VisiMisiBloc(VisiMisiRepository())..add(GetVisiMisiList()),

    在您的小部件树中:

    body: BlocProvider<VisiMisiBloc>(
                create: (_) => VisiMisiBloc(VisiMisiRepository())..add(GetVisiMisiList()), //initialising bloc within repository and hit event as well.
               
                child: BlocBuilder<VisiMisiBloc, VisiMisiState>(
                      builder: (context, state) {
                        if (state is VisiMisiInitial) {
                      
                          return Center(child: Text(state.toString()),);
                        } else if (state is VisiMisiError) {
                          return Center(child: Text(state.message),);
                        } else if (state is VisiMisiLoaded) {
                          return SingleChildScrollView(
                            child:  Container(
                              child: Column(
                                mainAxisAlignment: MainAxisAlignment.start,
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  _visiWidget(context, state),
                                  SizedBox(height: 20,),
                                  _misiWidget(context),
                                  SizedBox(height: 30,),
                                  _footerWidget(context)
                                ],
                              ),
                            ),
                          );
                        } 
    
                        return  Center(child: CircularProgressIndicator(),);
                      }
                  )
                ),
    

    这个答案也将解决Unhandled error NoSuchMethodError: The method 'getVisiMisi' was called on null 错误。

    【讨论】:

      【解决方案2】:

      要初始化存储库,您应该使用 RepositoryProvider。

      例如,类似的东西

      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MultiRepositoryProvider(
              providers: [
                RepositoryProvider<UserRepository>(
                  create: (context) => UserRepository(),
                ),
              ],
              child: MultiBlocProvider(
                  providers: [
                    BlocProvider<LoginBloc>(
                      create: (context) => LoginBloc(context.read<UserRepository>()),
                    ),
                  ],
                  child: Widget()));
        }
      }
      

      然后会自动初始化

      【讨论】:

        【解决方案3】:

        尝试像这样初始化存储库:

        class _VisiMisiPageState extends State<VisiMisiPage> {
          VisiMisiRepository repository;
        
          @override
          void initState(){
            super.initState();
            repository = VisiMisiRepositoryImpl( parameters here ); // add this one
          }
        

        【讨论】:

          猜你喜欢
          • 2020-10-10
          • 2020-08-03
          • 2020-05-06
          • 2020-02-27
          • 2021-08-02
          • 2021-01-06
          • 2020-06-17
          • 2022-08-11
          • 2020-09-03
          相关资源
          最近更新 更多