状态不佳:迁移到 flutter_bloc v8.0.1

Bad state: Migrate To flutter_bloc v8.0.1

我正在尝试解决与 Flutter Bloc 相关的问题。我正在编辑其他人的代码以使其适用于最新的 flutter_bloc 版本,但我无法这样做。有人可以重写我的代码以便我可以 运行 吗?我看到了很多答案,但我无法理解如何修复我自己的代码。

这是 all_categories_bloc.dart

的完整代码
    class AllCategoriesBloc extends Bloc<AllCategoriesEvent, AllCategoriesState> {
  AllCategoriesBloc({
    this.apiRepository,
  }) : super(AllCategoriesInitial()) {
    on<GetAllCategories>(_onGetAllCategories);
  }

  final ApiRepository apiRepository;

  Future<void> _onGetAllCategories(
    GetAllCategories event,
    Emitter<AllCategoriesState> emit,
  ) async {
    try {
      emit(const AllCategoriesLoading());

      final categoriesModel = await apiRepository.fetchCategoriesList();

      emit(AllCategoriesLoaded(categoriesModel));

      if (categoriesModel.error != null) {
        emit(AllCategoriesError(categoriesModel.error));
      }
    } catch (e) {
      emit(
        const AllCategoriesError(
          "Failed to fetch all categories data. Is your device online ?",
        ),
      );
    }
  }
}

all_categories_event.dart

的代码
abstract class AllCategoriesEvent extends Equatable {
  AllCategoriesEvent();
}

class GetAllCategories extends AllCategoriesEvent {

  @override
  List<Object> get props => null;

}

all_categories_state.dart

的代码
abstract class AllCategoriesState extends Equatable {
  const AllCategoriesState();
}

class AllCategoriesInitial extends AllCategoriesState {
  AllCategoriesInitial();

  @override
  List<Object> get props => [];
}

class AllCategoriesLoading extends AllCategoriesState {
  const AllCategoriesLoading();
  @override
  List<Object> get props => null;
}

class AllCategoriesLoaded extends AllCategoriesState {

  final CategoriesModel categoriesModel;
  const AllCategoriesLoaded(this.categoriesModel);

  @override
  List<Object> get props => [categoriesModel];
}

class AllCategoriesError extends AllCategoriesState {

  final String message;
  const AllCategoriesError(this.message);

  @override
  List<Object> get props => [message];
}

它抛出错误“错误状态:在没有注册事件处理程序的情况下调用了 add(GetAllCategories)。 确保通过 on((event, emit) {...})"

注册处理程序

我家里有这个 add(GetAllCategories)。 dart 文件,但解决方案是编辑我无法这样做的代码。有人可以重写最新的集团吗?我将不胜感激。

让我们逐步完成迁移指南:

  1. package:bloc v5.0.0: initialState has been removed. For more information check out #1304.

您应该简单地从您的 BLoC 中删除 AllCategoriesState get initialState => AllCategoriesInitial(); 部分。

  1. package:bloc v7.2.0 Introduce new on<Event> API. For more information, read the full proposal.

作为此迁移的一部分,删除了 mapEventToState 方法,每个事件都在构造函数中单独注册 on<Event> API.

首先,在构造函数中注册您的事件:

AllCategoriesBloc() : super(AllCategoriesInitial()) {
  on<GetAllCategories>(_onGetAllCategories);
}

然后,创建 _onGetAllCategories 方法:

Future<void> _onGetAllCategories(
  GetAllCategories event,
  Emitter<AllCategoriesState> emit,
) async {
  try {
    emit(const AllCategoriesLoading());

    final categoriesModel = await _apiRepository.fetchCategoriesList();

    emit(AllCategoriesLoaded(categoriesModel));

    if (categoriesModel.error != null) {
      emit(AllCategoriesError(categoriesModel.error));
    }
  } catch (e) {
    emit(
      const AllCategoriesError(
        "Failed to fetch all categories data. Is your device online ?",
      ),
    );
  }
}

请注意,您应该使用 Emitter<AllCategoriesState> 发射器,而不是使用生成器并产生下一个状态。

这里是迁移后的最终结果AllCategoriesBloc:

class AllCategoriesBloc extends Bloc<AllCategoriesEvent, AllCategoriesState> {
  AllCategoriesBloc() : super(AllCategoriesInitial()) {
    on<GetAllCategories>(_onGetAllCategories);
  }

  final ApiRepository _apiRepository = ApiRepository();

  Future<void> _onGetAllCategories(
    GetAllCategories event,
    Emitter<AllCategoriesState> emit,
  ) async {
    try {
      emit(const AllCategoriesLoading());

      final categoriesModel = await _apiRepository.fetchCategoriesList();

      emit(AllCategoriesLoaded(categoriesModel));

      if (categoriesModel.error != null) {
        emit(AllCategoriesError(categoriesModel.error));
      }
    } catch (e) {
      emit(
        const AllCategoriesError(
          "Failed to fetch all categories data. Is your device online ?",
        ),
      );
    }
  }
}

小费

您可以使用构造函数注入,而不是直接在 BLoC 中创建 ApiRepository 的实例:

class AllCategoriesBloc extends Bloc<AllCategoriesEvent, AllCategoriesState> {
  AllCategoriesBloc({
    required this.apiRepository,
  }) : super(AllCategoriesInitial()) {
    on<GetAllCategories>(_onGetAllCategories);
  }

  final ApiRepository apiRepository;

  ...
}

现在,在创建 BLoC 时,将存储库的实例传递给构造函数,如 AllCategoriesBloc(apiRepository: ApiRepository())。通过这种方式,您将能够通过模拟依赖项(在本例中,ApiRepository)正确地对您的 BLoC 进行单元测试。