简体   繁体   English

flutter_bloc:^6.1.1 不改变 state

[英]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 没有改变。

nav_bar_bloc.dart nav_bar_bloc.dart

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';
    }
  }
}

nav_bar_event.dart nav_bar_event.dart

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 {}

nav_bar_state.dart nav_bar_state.dart

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 {}

ui.dart ui.dart

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

dependency_injection.dart依赖注入.dart

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:更新:两个简短的例子:

  1. Using BlocProvider :使用BlocProvider
...
BlocProvider(
  create: (_) => sl<NavBarBloc>()..add(add(HomePageSelectEvent()),
  ...
)
...
  1. Saving the instance in you widget:将实例保存在您的小部件中:
...
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.

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