繁体   English   中英

Flutter Bloc - Flutter Bloc state 未更新

[英]Flutter Bloc - Flutter Bloc state not updating

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

集团

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());
    }
  }
}

STATE

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:在 null 上调用了方法“getVisiMisi”。

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

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

class _VisiMisiPageState extends State<VisiMisiPage> {
  VisiMisiRepository repository;

  @override
  void initState(){
    super.initState();
    repository = VisiMisiRepositoryImpl( parameters here ); // add this one
  }

要初始化存储库,您应该使用 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()));
  }
}

然后会自动初始化

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

第一个。 您刚刚创建了 VisiMisiRepository 的实例并且没有初始化。 并且您正在调用他们的方法,这就是为什么您收到错误Unhandled error NoSuchMethodError: The method 'getVisiMisi' was called on null.

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

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

替换这个:

create: (_) => VisiMisiBloc(repository),

有了这个:

create: (_) => 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错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM