flutter 当Map中的列表更改时,Blocbuilder不更新

vxqlmq5t  于 2022-11-26  发布在  Flutter
关注(0)|答案(2)|浏览(172)

bounty将在2天后过期。回答此问题可获得+50的声望奖励。flutter正在寻找来自知名来源的答案

我试图在我的map中的list发生变化时触发更新。类型是Map<String, List<int>>。基本上,列表中的一个整数发生了变化,但没有触发blockbuilder。尽管当我打印状态时,值被更新了。我使用了freezed。据我所知,freezed只为嵌套的@freezed对象提供了深层副本,但不为迭代对象提供。我'我看过一些解决这类问题的方法。例如,创建一个新的带有Map.from的Map,然后输出该Map。但是这并不会触发重建。有什么建议吗?
我的freezed状态为

onst factory RiskAttitudeState.loaded({
    required int customerId,
    required RiskAttitudeQuestionsInfo riskAttitude,
    required Map<String, List<int>> answerIds,
    @Default(FormzStatus.pure) FormzStatus status,
    int? finalRisk,
  }) = RiskAttitudeLoaded;

我在MapanswerIds中更新列表类型List<int>中的一个整数
下面是bloc未来_Map回答到状态(

String id, List<int> answerIds, Emitter<RiskAttitudeState> emit) async {

    await state.maybeMap(
      loaded: (RiskAttitudeLoaded loaded) async {
        if (loaded.answerIds.containsKey(id)) {
          loaded.answerIds.update(
            id,
            (_) => answerIds,
            ifAbsent: () {
              add(RiskAttitudeEvent.error(Exception('unknown Question ID: $id')));
              return answerIds;
            },
          );
        }

        emit(loaded.copyWith(answerIds: loaded.answerIds));
      },
      orElse: () async {},
    );
  }

如果我传递一个像这样的空Mapemit(loaded.copyWith(answerIds:{}));
构建器被触发。

e5nqia27

e5nqia271#

不幸的是,我也遇到了这个问题。如果你的算法需要改变列表中的一个项目,也许你可以从你的列表中删除这个项目,然后改变它的属性。之后,如果你把这个项目添加到列表中,构建器将被触发。

mkh04yzy

mkh04yzy2#

我尝试了一个小代码与cubit和Equatable和它的工作。关键是,你应该覆盖道具方法,并添加answerIds和其他字段,如果存在的道具和所有字段必须是最终的。
还要注意使用Map<String, List<int>>.from来填充Map。
所以state类看起来像这样:

class UcHandleState extends Equatable {
  final Map<String, List<int>> answerIds;
  const UcHandleState({
    required this.answerIds,
  });

  @override
  List<Object> get props => [
        answerIds,
      ];

  UcHandleState copyWith({
    Map<String, List<int>>? answerIds,
  }) {
    return UcHandleState(
      answerIds: answerIds != null
          ? Map<String, List<int>>.from(answerIds)
          : this.answerIds,
    );
  }
}

和一个简单的cubit类来管理事件,如下所示。在valueChanged中,我只是传递List<int>

class TestCubit extends Cubit<TestState> {
  TestCubit() : super(const TestState(answerIds: {'1': [1, 1]}));

  void valueChanged(List<int> newValues ) {
    Map<String, List<int>> test = Map<String, List<int>>.from(state.answerIds);
    test['1'] = newValues;
    emit(state.copyWith(
      answerIds: test,
    ));
  }
}

所以在UI中我调用cubit valueChanged()方法:

cubit.valueChanged(newValues:[ Random().nextInt(50), Random().nextInt(70)]);

并且blocBuilder被触发:

return BlocBuilder<UcHandleCubit, UcHandleState>(
        buildWhen: (prev, cur) =>
        prev.answerIds!= cur.answerIds,
        builder: (context, state) {
          print(state.answerIds.values);
         ....

相关问题