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

使用GetX时RxMap列表仅热重载后更新,Obx不自动刷新求助

Flutter GetX RxMap 不刷新 UI 问题排查与解决

问题根源

GetX 的 RxMap 仅监听顶层键值对的新增/删除/替换,如果 Map 中存储的是普通 List,修改 List 内部元素(如 add)不会触发 RxMap 的更新通知,导致 Obx 组件无法感知数据变化,只有热重载时才会刷新。

另外,ctrl.applicantDocuments.value[i] 报错是因为 value 是 RxMap 的受保护成员,外部不能直接访问,正确方式是通过 [] 操作符访问 Map 元素。


解决方案

方案1:将内部 List 改为 RxList

把 RxMap 的值类型换成 RxList,让每个 List 本身也具备可观察性,修改 List 时自动触发 UI 更新:

修改后的控制器代码

class MyAppliesController extends GetxController {  
  // 将 List 改为 RxList
  RxMap<int, RxList<NewDocumentsRequest>> applicantDocuments =
      <int, RxList<NewDocumentsRequest>>{}.obs;

  void addDocumentToList(
      int applicantId, NewDocumentsRequest document, VisaModel visaModel) {
    if (!applicantDocuments.containsKey(applicantId)) {
      // 初始化时创建 RxList
      applicantDocuments[applicantId] = <NewDocumentsRequest>[].obs;
    }
    bool documentExists = applicantDocuments[applicantId]!.any(
        (existingDocument) =>
            existingDocument.documentType == document.documentType);
    if (!documentExists) {
      if (applicantDocuments[applicantId]!.length <
          visaModel.visaApplicants![applicantId].visaDocuments!.length) {
        // 直接调用 RxList 的 add 即可触发更新
        applicantDocuments[applicantId]!.add(document);
      } else {
        print('Applicant already has 3 documents');
      }
    } else {
      errorSnackBar('alreadyDownload');
      errorSnackBar('alreadyDownload');
    }
  }
}

方案2:修改 List 后手动触发 RxMap 更新

如果不想修改 List 类型,可以在修改 List 后,通过重新赋值或调用 refresh() 强制触发 RxMap 的更新通知:

修改后的控制器代码(addDocumentToList 方法)

void addDocumentToList(
    int applicantId, NewDocumentsRequest document, VisaModel visaModel) {
  if (!applicantDocuments.containsKey(applicantId)) {
    applicantDocuments[applicantId] = [];
  }
  bool documentExists = applicantDocuments[applicantId]!.any(
      (existingDocument) =>
          existingDocument.documentType == document.documentType);
  if (!documentExists) {
    if (applicantDocuments[applicantId]!.length <
        visaModel.visaApplicants![applicantId].visaDocuments!.length) {
      final currentList = applicantDocuments[applicantId]!;
      currentList.add(document);
      // 重新赋值触发 RxMap 更新
      applicantDocuments[applicantId] = currentList;
      // 或者调用 refresh() 强制通知
      // applicantDocuments.refresh();
    } else {
      print('Applicant already has 3 documents');
    }
  } else {
    errorSnackBar('alreadyDownload');
    errorSnackBar('alreadyDownload');
  }
}

修正 UI 代码

  1. 将空判断移到 Obx 内部,确保响应式更新
  2. 移除错误的 .value 访问方式,直接通过 [] 获取元素

修改后的界面代码

Obx(() {
  final documents = ctrl.applicantDocuments[i];
  // 空判断放到 Obx 内部
  if (documents == null || documents.isEmpty) {
    return const SizedBox();
  }
  return ListView.builder(
      physics: const ScrollPhysics(),
      shrinkWrap: true,
      itemCount: documents.length,
      itemBuilder: (ctx, index) {
        return DownloadDocTile(
          title: documents[index].documentTypeName.toString() ?? '',
          trailing: Icon(
            FontAwesomeIcons.circleQuestion,
            color: AppColors.neutral700,
          ),
        );
      });
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:05:33