簡體   English   中英

如何依賴父BLOC保留子BLOC的state?

[英]How to keep state of child BLOC depending on parent BLOC?

如果一個 BLOC 可以與其他相關的 BLOC 一起工作,我需要一個建議或魔法踢。

我有這個結構building -> floors -> floorplan 所以我有三個 BLOC

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 會顯示一棵包含建築物樓層的樹。 lastSelectedFloorIdFloorBloc更改時,GUI 會顯示帶有平面圖的圖像。 該圖像可以縮放和滾動。

當我 go 從建築物頁面出來時,我需要保存當前的樓層選擇和所選圖像計划的比例/滾動偏移,並在我返回時恢復它(這就是我使用HyndratedBloc的原因)。 但是當建築物發生變化時(選擇新建築物),我需要為FloorPlanBloc重置所有以前的 state 。 所以我需要在FloorBlocFloorPlanBloc之間實現“協商”。 FloorBloc應該創建並返回FloorPlanBloc嗎? 或者FloorBloc是否應該為FloorPlanBloc保留 state,然后在創建時將其傳遞給FloorPlanBloc 我有點迷路所以也許有人給我任何幫助?

您可以將Bloc的一個dependency inject另一個並監聽它的事件。 像這樣:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM