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

发布于 2025-01-14 00:36:33 字数 2324 浏览 3 评论 0原文

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

这是 all_categories_bloc.dart 的完整代码 all_categories_event.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_state.dart

abstract class AllCategoriesEvent extends Equatable {
  AllCategoriesEvent();
}

class GetAllCategories extends AllCategoriesEvent {

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

}

的代码

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){...}) 注册一个处理程序“

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

I am trying to fix an issue related to Flutter Bloc. I am editing someone else code to make it work with the latest flutter_bloc version but I am unable to do so. Can someone do a rewrite for my code so I can run it? I saw many answers but I am unable to understand how to fix my own code.

This is the complete code for 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 ?",
        ),
      );
    }
  }
}

Code for all_categories_event.dart

abstract class AllCategoriesEvent extends Equatable {
  AllCategoriesEvent();
}

class GetAllCategories extends AllCategoriesEvent {

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

}

Code for 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];
}

It throws an error "Bad state: add(GetAllCategories) was called without a registered event handler.
Make sure to register a handler via on((event, emit) {...})"

I have this add(GetAllCategories) in my home. dart file but the solution is to edit this code which I am unable to do so. Can someone do a rewrite for the latest bloc? I would be thankful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北方的巷 2025-01-21 00:36:33

让我们逐步了解迁移指南:

  1. <块引用>

    package:bloc v5.0.0:initialState 已被删除。有关更多信息,请查看 #1304

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

  1. <块引用>

    package:bloc v7.2.0 在上引入新内容API。如需了解更多信息,请阅读完整提案

作为此迁移的一部分,mapEventToState 方法已被删除,每个事件均使用 on 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<,而不是使用生成器并生成下一个状态。 /代码> 发射器。

以下是迁移 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 进行单元测试。

Let's get through the migration guide step by step:

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

You should simply remove the AllCategoriesState get initialState => AllCategoriesInitial(); portion from your BLoC.

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

As a part of this migration, the mapEventToState method was removed, each event is registered in the constructor separately with the on<Event> API.

First of all, register your events in the constructor:

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

Then, create the _onGetAllCategories method:

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

Notice, that instead of using generators and yielding the next state, you should use the Emitter<AllCategoriesState> emitter.

Here is the final result of the migrated 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 ?",
        ),
      );
    }
  }
}

Bonus tip

Instead of creating an instance of ApiRepository inside the BLoC directly, you can use the constructor injection:

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

  final ApiRepository apiRepository;

  ...
}

Now, when creating BLoC, pass the instance of the repository to the constructor, like AllCategoriesBloc(apiRepository: ApiRepository()). This way you will be able to properly unit test your BLoC by mocking dependencies (in this case, ApiRepository).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文