Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 按集团管理全球活动_Flutter_Dart_Bloc - Fatal编程技术网

Flutter 按集团管理全球活动

Flutter 按集团管理全球活动,flutter,dart,bloc,Flutter,Dart,Bloc,我试图找到管理异步查询的解决方案。例如,我有网店,我想在城市发生变化时更新所有产品和类别。我不想在ui上保留所有异步逻辑。为了实现这一结果,我创建了以下集团: class AppEvent { String message; AppEvent({this.message = ''}); } class EventsBlock extends Bloc<AppEvent, AppEvent> { EventsBlock() : super(AppEvent());

我试图找到管理异步查询的解决方案。例如,我有网店,我想在城市发生变化时更新所有产品和类别。我不想在ui上保留所有异步逻辑。为了实现这一结果,我创建了以下集团:

class AppEvent {
  String message;

  AppEvent({this.message = ''});
}

class EventsBlock extends Bloc<AppEvent, AppEvent> {
  EventsBlock() : super(AppEvent());
 
  @override
  Stream<AppEvent> mapEventToState(AppEvent event) async* {
    yield event;
  }
}

final events = EventsBlock();
类上诉{
字符串消息;
AppEvent({this.message=''});
}
类EventsBlock扩展了Bloc{
EventsBlock():super(AppEvent());
@凌驾
流mapEventToState(AppEvent事件)异步*{
产量事件;
}
}
最终事件=EventsBlock();
然后,我可以这样使用它:

class CityCubit() {
  CityCubit() : super(CityState());  
  
  Future<void> changeCity() async {
    await api.changeCity();
    events.add(AppEvent(message: 'cityChanged'));   
  }
}

class CategoryCubit extends Cubit<CategoryState> {
  CategoryCubit() : super(CategoryEmptyState()) {
    events.stream.listen((e) {
        if(e.message == 'cityChanged') {
            fetchCategories();
        }
      });
  };

  Future<void> fetchCategories() async {
    //fetch categories
  }
}

class ProductCubit extends Cubit<ProductState> {
  ProductCubit() : super(ProductEmptyState()) {
    events.stream.listen((e) {
        if(e.message == 'cityChanged') {
            fetchProducts();
        }
      });
  };

  Future<void> fetchProducts() async {
    //fetch products
  }
}
class CityCubit(){
CityCubit():超级(CityState());
Future changeCity()异步{
等待api.changeCity();
添加(AppEvent(消息:“cityChanged”);
}
}
类CategoryCubit扩展了Cubit{
CategoryCubit():超级(CategoryEmptyState()){
events.stream.listen((e){
如果(e.message=='cityChanged'){
fetchCategories();
}
});
};
Future fetchCategories()异步{
//获取类别
}
}
类ProductCubit扩展了Cubit{
ProductCubit():超级(ProductEmptyState()){
events.stream.listen((e){
如果(e.message=='cityChanged'){
获取产品();
}
});
};
Future fetchProducts()异步{
//取货
}
}

这有点像事件总线模式。但我不确定使用bloc是否正确。我曾尝试使用redux+redux saga,但它有很多样板文件,我相信Flatter有更好的解决方案来管理类似的事情。

您的总体想法是可以的,但我看不出真正需要
EventsBloc
类。事实上,有点奇怪的是,您对事件和这个集团的状态使用同一个类,并简单地生成您收到的事件。这就像
EventsBloc
可以是一个简单的流

下面是一个方法,将
CityCubit
转化为一个实际的bloc(还包括一些错误处理,这是您可以优雅地使用bloc完成的):


我最终得到了以下代码:

class CityChangedEvent {
  int cityId;

  CityChangedEvent(this.cityId);
}

EventBus eventBus = EventBus();

mixin EventBusMixin {
  StreamSubscription<T> listenEvent<T>(void Function(T) subscription) =>
      eventBus.on<T>().listen(subscription);

  void shareEvent<S>(S event) => eventBus.fire(event);
}

class CityCubit extends CityCubit<CityState> with EventBusMixin {
  CityCubit() : super(CityInitialState());        

  Future<void> changeCity(cityId) async {
    try {
      emit(ChangeCityLoadingState());
      final result = await api.changeCity(cityId);
      if(result.success) {
        emit(ChangeCitySuccessState());
        shareEvent(CityChangedEvent(cityId));   
      }
    } catch (_) {
      emit(ChangeCityErrorState());
    }
  }
}

class CategoryCubit extends Cubit<CategoryState> with EventBusMixin {
  CategoryCubit() : super(CategoryEmptyState()) {
     listenEvent<CityChangedEvent>((e) {
        fetchCategories(e.cityId);
     );
  }

  Future<void> fetchCategories(cityId) async {
    try {
      emit(CategoryLoadingState());
      final categoriesList = await fetchCategoriesApi();
      emit(CategoryLoadedState(categories: categoriesList));
    } catch (_) {
      emit(CategoryErrorState());
    }
  }
}
class CityChangedEvent{
国际城市ID;
CityChangedEvent(this.cityId);
}
EventBus EventBus=EventBus();
mixin事件busmixin{
StreamSubscription listenEvent(无效函数(T)订阅)=>
eventBus.on().listen(订阅);
无效共享事件=>eventBus.fire(事件);
}
类CityCubit使用EventBusMixin扩展了CityCubit{
CityCubit():超级(CityInitialState());
Future changeCity(cityId)异步{
试一试{
发射(ChangeCityLadingState());
最终结果=等待api.changeCity(城市ID);
如果(结果、成功){
发射(ChangeCitySuccessState());
共享事件(CityChangedEvent(cityId));
}
}接住{
发射(ChangeCityErrorState());
}
}
}
类CategoryCubit使用EventBusMixin扩展了Cubit{
CategoryCubit():超级(CategoryEmptyState()){
Listenvent((e){
(e.cityId);
);
}
未来fetchCategories(cityId)异步{
试一试{
emit(CategoryLoadingState());
final categoriesList=await fetchCategoriesApi();
emit(CategoryLoadedState(categories:categoriesList));
}接住{
emit(CategoryErrorState());
}
}
}

现在,我可以在集团之间进行通信,而无需实例化或注入其实例。多亏了这个库,问题在于我需要在每个页面(类别、产品等)上注入cityBloc实例.我必须在widget build内部完成,并将其传递给其他bloc/cubit构造函数。如果我将此块设置为singleton并直接在其他类中侦听事件会怎么样?这是正确的方法吗?我想我找到了解决方案。
instanceOfCityBloc.listen((cityState) {
  if(cityState is CityCitiesLoaded){
    // do stuff
  }
});
class CityChangedEvent {
  int cityId;

  CityChangedEvent(this.cityId);
}

EventBus eventBus = EventBus();

mixin EventBusMixin {
  StreamSubscription<T> listenEvent<T>(void Function(T) subscription) =>
      eventBus.on<T>().listen(subscription);

  void shareEvent<S>(S event) => eventBus.fire(event);
}

class CityCubit extends CityCubit<CityState> with EventBusMixin {
  CityCubit() : super(CityInitialState());        

  Future<void> changeCity(cityId) async {
    try {
      emit(ChangeCityLoadingState());
      final result = await api.changeCity(cityId);
      if(result.success) {
        emit(ChangeCitySuccessState());
        shareEvent(CityChangedEvent(cityId));   
      }
    } catch (_) {
      emit(ChangeCityErrorState());
    }
  }
}

class CategoryCubit extends Cubit<CategoryState> with EventBusMixin {
  CategoryCubit() : super(CategoryEmptyState()) {
     listenEvent<CityChangedEvent>((e) {
        fetchCategories(e.cityId);
     );
  }

  Future<void> fetchCategories(cityId) async {
    try {
      emit(CategoryLoadingState());
      final categoriesList = await fetchCategoriesApi();
      emit(CategoryLoadedState(categories: categoriesList));
    } catch (_) {
      emit(CategoryErrorState());
    }
  }
}