You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

独立BLoC实例异常:表单清除时误删历史图片数据求助

问题原因分析

你的核心问题出在每次indexCubit触发BlocBuilder重建时,都会重复创建ShowImageCubit实例并添加到listCubit,同时重复添加空数组到listFiles,导致listCubit和listFiles的元素数量不断膨胀,且与listProduct的对应关系完全错乱:

  1. 当indexCubit.change()触发重建时,List.generate(listProduct.length, ...)会循环执行listProduct.length次,每次都执行listCubit.add(showImageCubit)和listFiles.add(imageFiles),这会让listCubit的长度变成原长度 + listProduct.length,而非和listProduct保持一致的长度。
  2. 此时ProductInput接收的bloc: listCubit[index]已经不是最初绑定的ShowImageCubit实例,而是某次重建时新增的空Cubit,所以显示的图片消失,看起来像是被"删除"了。
  3. 另外ProductInput使用UniqueKey()会强制每次重建都销毁旧控件、创建新控件,进一步加剧状态丢失问题。
修复方案

1. 同步listProduct、listCubit、listFiles的创建与删除

不要在List.generate里动态创建Cubit和文件数组,而是在添加新商品表单时同步初始化对应的Cubit和空数组;删除时同步移除对应元素:

void addProduct(ModelProductOrder val) {
  listProduct.add(val);
  // 同步创建对应Cubit和空文件数组
  listCubit.add(ShowImageCubit());
  listFiles.add([]);
  indexCubit.change(Random().nextInt(100000));
}

2. 修改ListView的构建逻辑

在List.generate里直接使用已有的listCubit[index]和listFiles[index],不再重复创建和添加:

BlocBuilder(
  bloc: indexCubit,
  builder: (context, state) {
    return ListView(
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      padding: EdgeInsets.zero,
      children: List.generate(
        listProduct.length,
        (index) {
          // 移除此处的Cubit和数组创建代码
          return ProductInput(
            key: ValueKey(index), // 改用ValueKey(index),保证同index对应同控件
            callBack: (val) {
              isUpdate = false;
              listProduct[index] = val;
              indexCubit.change(Random().nextInt(100000));
            },
            dataUpdate: listProduct[index],
            bloc: listCubit[index], // 直接使用已有的Cubit实例
            onDelete: () {
              DialogItem.showMsg(
                context: context,
                title: 'Xác nhận xoá sản phẩm',
                msg: "Bạn có muốn xoá sản phẩm này?",
                onConfirm: () {
                  listProduct.removeAt(index);
                  listCubit.removeAt(index);
                  listFiles.removeAt(index);
                  indexCubit.change(Random().nextInt(100000));
                  Navigator.pop(context);
                },
              );
            },
            listFiles: listFiles[index], // 直接使用已有的文件数组
          );
        },
      ),
    );
  },
),

3. 确保clearInput只操作当前表单的Cubit

检查ProductInput内部的showImage是否是传入的widget.bloc实例,避免误操作其他表单的状态:

// 在ProductInput类中
ShowImageCubit get showImage => widget.bloc;

void clearInput() {
  seriesCode.clear();
  warrantyCode.clear();
  showImage.clear(); // 仅操作当前表单绑定的Cubit,不会影响其他表单
}

4. 移除不必要的setState

删除操作里的空setState()可以移除,改用indexCubit.change()触发BlocBuilder重建即可,保持状态管理统一。

内容的提问来源于stack exchange,提问作者nghkh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 09:07:07