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