flutter 如何根据父BLOC保持子BLOC的状态?

egdjgwm8  于 2023-01-18  发布在  Flutter
关注(0)|答案(1)|浏览(190)

我需要一个建议或魔术踢的情况下如何一个区块可以与其他相关的区块工作。
我有这样的结构building-〉floors-〉floorplan。所以我有三个块

class BuildingBloc extends Bloc {
  // .. exposes state with lastSelectedBuildingId
}

class FloorBloc extends HydratebBloc {
  // ... exposes state with lastSelectedFloorId
  // ... refreshes (loads) floors for a specific building
  // ... manages current selection

  // Two ways to manage selected building
  // 1. Use class member `buildingId` and use it for getting floors
  // 2. Pass `buildingId` to `getFloors` method w/o passing it to constructor.
  FloorBloc(this.buildingId) : super(...)

  Future<BuildingFloor> getFloors([int? buildingId]) {
    ...
  }
}

class FloorPlanBloc extends HydratedBloc {
  // ... exposes state with scale and scrollOffset
  // ... allows to zoom image and scroll it.
}

BuildingBloclastSelectedBuildingId被改变时,GUI显示带有建筑物楼层的树。当FloorBloclastSelectedFloorId被改变时,GUI显示带有楼层平面图的图像。该图像可以缩放和滚动。
当我离开建筑物页面时,我需要保存当前楼层选择和所选图像平面的比例/滚动偏移,并在返回时恢复(这就是为什么我使用HyndratedBloc)。但是当建筑物改变时(选择了新的)我需要重置FloorPlanBloc之前的所有状态。因此,我需要在FloorBlocFloorPlanBloc之间实现“协商”。FloorBloc应该创建并返回FloorPlanBloc吗?或者FloorBloc应该保留FloorPlanBloc的状态,然后在创建时将其传递给FloorPlanBloc吗?我有点困惑,也许有人能给我任何帮助?

unhi4e5o

unhi4e5o1#

你可以dependency inject``Bloc一个到另一个并监听它的事件。

class BuildingBloc extends Bloc {
  BuildingBloc(super.initialState);
  // .. exposes state with lastSelectedBuildingId
}

class FloorBloc extends Bloc {
  final BuildingBloc buildingBloc;
  FloorBloc(this.buildingBloc, super.initialState) {
    // listening on BuildingBloc events
    buildingBloc.stream.listen((event) {
      // reacting to some event from BuildingBloc
      if (event is BuildingBlocEvent) {
        // ... do something
        getFloors(event.buildingId); // e.g.
      }
    });
  }

  Future<BuildingFloor> getFloors([int? buildingId]) async {
    // ...
    await Future.delayed(Duration.zero);
    return BuildingFloor();
  }
}

class FloorPlanBloc extends Bloc {
  final FloorBloc floorBloc;
  // inject FloorBloc
  FloorPlanBloc(this.floorBloc, super.initialState) {
    // listening on FloorBloc events
    floorBloc.stream.listen((event) {
      // reacting to some event from FloorBloc
      if (event is FloorBlocEvent) {
        // ... do something
      }
    });
  }
}

因此,您将向它们注入BlocProviderMultiBlocProvider,如下所示:

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider(
          create: (ctx) => BuildingBloc(BuildingBlocInitialState()),
        ),
        BlocProvider(
          create: (ctx) => FloorBloc(ctx.read<BuildingBloc>(), FloorBlocInitialState()),
        ),
        BlocProvider(
          create: (ctx) => FloorPlanBloc(ctx.read<FloorBloc>(), FloorPlanBlocInitialState()),
        ),
      ],
      child: MaterialApp(home: HomePage()),
    );
  }
}

相关问题