[英]flutter_bloc: ^6.1.1 not changing state
I am using flutter_bloc: ^6.1.1 along with dependency injection get_it: ^5.0.6.我正在使用flutter_bloc:^6.1.1以及依赖注入get_it:^5.0.6。 The state is not changing when I submit event to the bloc.
当我向集团提交事件时,state 没有改变。
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
import '../../../../../core/error/failures.dart';
import '../../../../../core/usecases/usecase.dart';
import '../../../domain/entities/fixtures_entities.dart';
import '../../../domain/entities/prediction_entities.dart';
import '../../../domain/usecases/get_fixtures.dart';
import '../../../domain/usecases/get_predictions.dart';
part 'nav_bar_event.dart';
part 'nav_bar_state.dart';
const String SERVER_FAILURE_MESSAGE = 'SERVER FAILURE. TRY AGAIN LATER';
const String CACHE_FAILURE_MESSAGE = 'CACHE FAILURE';
class NavBarBloc extends Bloc<NavBarEvent, NavBarState> {
final GetBasicFixtures getBasicFixtures;
final GetPredictions getPredictions;
NavBarBloc({
@required this.getBasicFixtures,
@required this.getPredictions,
}) : super(NavBarInitialState());
@override
Stream<NavBarState> mapEventToState(
NavBarEvent event,
) async* {
print(event);
// FIXTURES EVENT
// yield HomePageLoadingState();
if (event is HomePageSelectEvent) {
Either<Failure, List<BasicFixturesEntity>> response =
await getBasicFixtures(NoParams());
yield* response.fold((failure) async* {
yield HomePageLoadFailureState(message: _mapFailureToMessage(failure));
}, (fixtures) async* {
print(fixtures[0].away);
yield HomePageLoadSuccessState(fixtures: fixtures);
});
} // GET PREDICTIONS EVENT
else if (event is PredictionPageSelectEvent) {
yield PredictionPageLoadingState();
Either<Failure, List<PredictionEntity>> response =
await getPredictions(NoParams());
yield* response.fold((failure) async* {
yield PredictionPageLoadFailureState(
message: _mapFailureToMessage(failure));
}, (predictions) async* {
yield PredictionPageLoadSuccessState(predictions: predictions);
});
} // NEWS EVENT
else if (event is NewsPageSelectEvent) {
yield NewsPageLoadingState();
yield NewsPageLoadSuccessState();
} // ACCOUNT EVENT
else if (event is AccountPageSelectEvent) {
yield AccountPageLoadingState();
yield AccountPageLoadSuccessState();
}
}
String _mapFailureToMessage(Failure failure) {
switch (failure.runtimeType) {
case ServerFailure:
return SERVER_FAILURE_MESSAGE;
case CacheFailure:
return CACHE_FAILURE_MESSAGE;
default:
return 'UNEXPECTED ERROR';
}
}
}
part of 'nav_bar_bloc.dart';
abstract class NavBarEvent extends Equatable {
const NavBarEvent();
@override
List<Object> get props => [];
}
class HomePageSelectEvent extends NavBarEvent {}
class PredictionPageSelectEvent extends NavBarEvent {}
class NewsPageSelectEvent extends NavBarEvent {}
class AccountPageSelectEvent extends NavBarEvent {}
part of 'nav_bar_bloc.dart';
abstract class NavBarState extends Equatable {
const NavBarState();
@override
List<Object> get props => [];
}
class NavBarInitialState extends NavBarState {}
// Initial HOME PAGE [FIXTURES PAGE]
class HomePageLoadingState extends NavBarState {}
class HomePageLoadSuccessState extends NavBarState {
final List<BasicFixturesEntity> fixtures;
HomePageLoadSuccessState({@required this.fixtures});
@override
List<Object> get props => [fixtures];
}
class HomePageLoadFailureState extends NavBarState {
final String message;
HomePageLoadFailureState({@required this.message});
@override
List<Object> get props => [message];
}
// PREDICTION PAGE
class PredictionPageLoadingState extends NavBarState {}
class PredictionPageLoadSuccessState extends NavBarState {
final List<PredictionEntity> predictions;
PredictionPageLoadSuccessState({@required this.predictions});
@override
List<Object> get props => [predictions];
}
class PredictionPageLoadFailureState extends NavBarState {
final String message;
PredictionPageLoadFailureState({@required this.message});
@override
List<Object> get props => [message];
}
// NEWS PAGE
class NewsPageLoadingState extends NavBarState {}
class NewsPageLoadSuccessState extends NavBarState {}
class NewsPageLoadFailureState extends NavBarState {}
// ACCOUNT PAGE
class AccountPageLoadingState extends NavBarState {}
class AccountPageLoadSuccessState extends NavBarState {}
class AccountPageLoadailureState extends NavBarState {}
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../injection_containers/injection_container.dart';
import '../bloc/nav_bar_bloc/nav_bar_bloc.dart';
import '../widgets/core/navbar.dart';
import 'account_page/account_page.dart';
import 'fixtures_page/fixtures_page.dart';
import 'news_page/news_page.dart';
import 'prediction_page/prediction_page.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
sl<NavBarBloc>().add(HomePageSelectEvent());
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
bottomSheet: NavBar(),
body: BlocProvider(
create: (_) => sl<NavBarBloc>(),
child:
// ignore: missing_return
BlocBuilder<NavBarBloc, NavBarState>(builder: (context, state) {
print(state);
// HOME PAGE aka. FIXTURES PAGE
if (state is HomePageLoadFailureState) {
return Center(child: Text(state.message));
} else if (state is HomePageLoadSuccessState) {
return FixturesPage(fixtures: state.fixtures);
} else if (state is HomePageLoadingState) {
return Center(child: CircularProgressIndicator());
}
// PREDICTION PAGE
else if (state is PredictionPageLoadingState) {
return Center(child: CircularProgressIndicator());
} else if (state is PredictionPageLoadFailureState) {
return Center(child: Text(state.message));
} else if (state is PredictionPageLoadSuccessState) {
return PredictionPage(predictions: state.predictions);
}
// ACCOUNT PAGE
else if (state is AccountPageLoadingState) {
return AccountPage();
} else if (state is AccountPageLoadSuccessState) {
return AccountPage();
} else if (state is AccountPageLoadailureState) {
return AccountPage();
}
// NEWS PAGE
else if (state is NewsPageLoadingState) {
return NewsPage();
} else if (state is NewsPageLoadSuccessState) {
return NewsPage();
} else if (state is NewsPageLoadFailureState) {
return NewsPage();
} else if (state is NavBarInitialState) {
return Center(
child: Text(
"loading",
style: TextStyle(color: Colors.white),
));
}
})));
}
}
import 'package:connectivity/connectivity.dart';
import 'package:get_it/get_it.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../core/network/network_info.dart';
import '../features/predictor/data/datasources/local_data_source/fixtures_local_data_source.dart';
import '../features/predictor/data/datasources/local_data_source/prediction_local_data_source.dart';
import '../features/predictor/data/datasources/remote_data_source/fixtures_remote_data_source.dart';
import '../features/predictor/data/datasources/remote_data_source/prediction_remote_data_source.dart';
import '../features/predictor/data/datasources/token_access.dart';
import '../features/predictor/data/repositories/fixtures_repositories_impl.dart';
import '../features/predictor/data/repositories/prediction_repositories_impl.dart';
import '../features/predictor/domain/repositories/fixtures_repositories.dart';
import '../features/predictor/domain/repositories/prediction_repositories.dart';
import '../features/predictor/domain/usecases/get_fixtures.dart';
import '../features/predictor/domain/usecases/get_predictions.dart';
import '../features/predictor/domain/usecases/submit_prediction.dart';
import '../features/predictor/presentation/bloc/nav_bar_bloc/nav_bar_bloc.dart';
import '../features/predictor/presentation/bloc/prediction_submit_bloc/prediction_submit_bloc.dart';
GetIt sl = GetIt.instance;
Future<void> init() async {
// NavBarBloc
sl.registerFactory<NavBarBloc>(
() => NavBarBloc(getBasicFixtures: sl(), getPredictions: sl()));
// SubmitPredictionBloc
sl.registerFactory<PredictionSubmitBloc>(
() => PredictionSubmitBloc(submitPrediction: sl()));
// Validate token
sl.registerLazySingleton<ValidateToken>(() => ValidateTokenImpl());
/// usecase
///
// Fixtures
sl.registerLazySingleton(() => GetBasicFixtures(repository: sl()));
// Get-predictions
sl.registerLazySingleton(() => GetPredictions(repository: sl()));
// submit-prediction
sl.registerLazySingleton(() => SubmitPrediction(predictionRepository: sl()));
/// repository
///
// Fixtures
sl.registerLazySingleton<BasicFixturesRepository>(() =>
BasicFixturesRepositoryImpl(
localDataSource: sl(), networkInfo: sl(), remoteDataSource: sl()));
// Prediction
sl.registerLazySingleton<PredictionRepository>(() => PredictionRepositoryImpl(
localDataSource: sl(), networkInfo: sl(), remoteDataSource: sl()));
/// Data Source
/// Remote Date Source
///
// Fixtures
sl.registerLazySingleton<BasicFixturesRemoteDataSource>(() =>
BasicFixturesRemoteDataSourceImpl(client: sl(), validateToken: sl()));
// Prediction
sl.registerLazySingleton<PredictionsRemoteDataSource>(
() => PredictionsRemoteDataSourceImpl(client: sl(), validateToken: sl()));
/// Local Data Source
///
// Fixtures
sl.registerLazySingleton<BasicFixturesLocalDataSource>(
() => BasicFixturesLocalDataSourceImpl(sharedPreferences: sl()));
// Prediction
sl.registerLazySingleton<PredictionsLocalDataSource>(
() => PredictionLocalDataSourceImpl(sharedPreferences: sl()));
// External
sl.registerLazySingleton<NetworkInfo>(() => NetworkInfoImpl(sl()));
final sharedPreferences = await SharedPreferences.getInstance();
sl.registerLazySingleton(() => sharedPreferences);
sl.registerLazySingleton(() => http.Client());
sl.registerLazySingleton(() => Connectivity());
}
Everything is working fine except the bloc is is not changing its state.一切正常,除了集团没有改变其 state。 It's stuck in initial state.
它卡在初始 state 中。 The code is working properly as it is making API request to the server.
代码工作正常,因为它正在向服务器发出 API 请求。
The problem is that you have registered NavBarBloc
as a factory.问题是您已将
NavBarBloc
注册为工厂。 So whenever you call sl<NavBarBloc>()
a new instance of the bloc is created.因此,每当您调用
sl<NavBarBloc>()
时,都会创建一个新的 bloc 实例。
Thus when you have called sl<NavBarBloc>().add(HomePageSelectEvent())
, the event is added to another instance, not the one you have passed to bloc builder.因此,当您调用
sl<NavBarBloc>().add(HomePageSelectEvent())
时,该事件将添加到另一个实例,而不是您传递给 bloc builder 的那个实例。
UPDATE: Two short examples:更新:两个简短的例子:
BlocProvider
:BlocProvider
:...
BlocProvider(
create: (_) => sl<NavBarBloc>()..add(add(HomePageSelectEvent()),
...
)
...
...
NavBarBloc navBarBloc;
@override
void initState() {
super.initState();
navBarBloc = sl<NavBarBloc>()..add(HomePageSelectEvent());
}
@override
void dispose() {
navBarBloc.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
bottomSheet: NavBar(),
body: BlocProvider.value(
value: navBarBloc,
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.