alibaba / fish-redux

An assembled flutter application framework.
https://github.com/alibaba/fish-redux
Apache License 2.0
7.33k stars 843 forks source link

page结构和数据流向 #406

Open KeeepTrying opened 5 years ago

KeeepTrying commented 5 years ago

component state由page state设置值,那是不是说子组件中发生变化最终都需要diaptch给page去改变,然后从上至下,通过connect改变component state

页面结构:顶部TabBar,主体TabBarView,切换tabbar缓存数据,下次切回来不再请求数据

class HomeState implements Cloneable<HomeState> {
  TabController tabController;
  String typeCode = '';
  List<TypeItem> typeList = [];
  // {typeCode, ProgramState}
  Map<String, ProgramState> typeProgramMap = {};

  @override
  HomeState clone() {
    return HomeState()
      ..tabController = tabController
      ..typeCode = typeCode
      ..typeList = typeList
      ..typeProgramMap = typeProgramMap;
  }
}

class TabbarConnector extends ConnOp<HomeState, TabbarState> {
  get(HomeState state) {
    return TabbarState()
      ..tabController = state.tabController
      ..typeCode = state.typeCode
      ..typeList = state.typeList;
  }

  set(HomeState state, TabbarState tabbarState) {
    state..typeCode = tabbarState.typeCode;
  }
}

class ProgramAdapter extends DynamicFlowAdapter<HomeState> {
  ProgramAdapter()
      : super(
          pool: <String, Component<Object>>{
            'program': ProgramComponent(),
          },
          connector: _ProgramConnector(),
        );
}

class _ProgramConnector extends ConnOp<HomeState, List<ItemBean>> {
  @override
  List<ItemBean> get(HomeState state) {
    if (state.typeProgramMap.isNotEmpty) {
      final list = List<ItemBean>();
      state.typeList.forEach((typeItem) {
        ProgramState programState = state.typeProgramMap[typeItem.typeCode];
        list.add(ItemBean('program', programState));
      });
      return list;
    } else {
      return <ItemBean>[];
    }
  }

  @override
  void set(HomeState state, List<ItemBean> items) {}
}

class TabbarState implements Cloneable<TabbarState> {
  TabController tabController;
  String typeCode;
  List<TypeItem> typeList;

  @override
  TabbarState clone() {
    return TabbarState()
      ..tabController = tabController
      ..typeCode = typeCode
      ..typeList = typeList;
  }
}

class ProgramState implements Cloneable<ProgramState> {
  List<ProgramItem> programList = [];
  bool hasMore = false;
  BannerState bannerState = BannerState();
  RefreshController refreshController;
  ProgramState() : refreshController = RefreshController(initialRefresh: false);

  @override
  ProgramState clone() {
    return ProgramState()
      ..bannerState = bannerState
      ..programList = programList
      ..refreshController = refreshController;
  }
}

class BannerConnector extends ConnOp<ProgramState, BannerState> {
  @override
  BannerState get(ProgramState state) {
    return state.bannerState;
  }

  @override
  void set(ProgramState state, BannerState subState) {
    state.bannerState = subState;
  }
}

page.buildView TabBarView:
Widget _buildTabView(TypeItem typeItem) {
    final String typeCode = typeItem.typeCode;
    final currentIndex =
        state.typeList.indexWhere((type) => type.typeCode == typeCode);
    return LayoutBuilder(
      key: Key(typeItem.typeCode),
      builder: (BuildContext context, BoxConstraints constraints) {
        return adapter.itemBuilder(context, currentIndex);
      },
    );
  }

tabbarComponent切换typeCode后,需要更新pageState.typeCode,没有缓存数据,page.effect通过typeCode请求更新typeProgramMap[typeCode],然后再同步更新到tabbarComponent和programComponent中吗?感觉整个过程很是繁琐,而且性能不佳,刚接触,不知道是否理解有误

zhangruiyu commented 5 years ago

个人感觉这个方法并不好,但是没有其他办法,你给问题打开 大家看看呢

hzgotb commented 5 years ago

按设计来说,确实数据是自上而下的。好处在于页面数据集中管理。不好的地方在于如果页面复杂度高,组件嵌套度深,写代码的时候会比较枯燥。 至于性能,和更多改进,需要社区的讨论和反馈。

KeeepTrying commented 5 years ago

请问我这种写法符合fish-redux设计理念吗?还有更好的方案吗?

zhangruiyu commented 5 years ago

@zjuwjf 实在不知道怎么解决 0-0大哥能给个方式吗

zhangruiyu commented 5 years ago

在adapter外层套个component吗,链接给adapter数据时候,再去分发component里的对应的type数据,这样感觉可以解决,但是多套了层component

zhangruiyu commented 5 years ago

好乱啊 只能一个一注册.不会 等大哥们解决了

hzgotb commented 5 years ago

对于重复数据的话,可以使用mixin

KeeepTrying commented 5 years ago

@hzgotb 能都对上述例子写个mixin,感觉没哪个切入点能用上mixin,实体类上吗?

zhangruiyu commented 5 years ago

@zjuwjf

zhangruiyu commented 5 years ago

@zjuwjf 大哥 能给个思路吗

zhangruiyu commented 5 years ago

@zjuwjf 每日一问

xmsz commented 4 years ago

同样情况

hasonguo commented 4 years ago

mark 数据流向必须由page流给component