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

Flutter如何修改不可修改Map?Provider修改订单数据报错

解决Provider中修改orders列表的两类报错问题

问题重现

在Provider中定义了如下orders列表:

List orders=[];
void getOrders(){
  orders = [
        {"id":1,
        "order":[
                {"id":1,"name":"mike"},
                {"id":2,"name":"john"},
                {"id":3,"name":"smith"}
                ]
       },
        {"id":1,
        "order":[
                {"id":1,"name":"roz"},
                {"id":2,"name":"sam"},
                {"id":3,"name":"ruby"}
                ]
       },
 ];
  notifyListeners();
}

尝试第一种修改方式时:

void changeOrder(orderIndex,item){
   orders[orderIndex].update("order",(val)=>item);
   notifyListeners();
}

报错:type '(dynamic) => dynamic' is not a subtype of type '(Object) => Object' of 'update'

尝试第二种修改方式时:

void changeOrder(orderIndex,item){
   orders[orderIndex]["order"]=item;
   notifyListeners();
}

报错:Unsupported operation: Cannot modify unmodifiable map

补充说明:changeOrder方法中的item来自页面中的代码var item = List.from(orders[index]);

原因分析

  1. 类型不匹配报错:orders未指定泛型,默认是List<dynamic>,其中的Map也是动态类型,Map.update()方法要求回调函数的返回类型为Object,但当前匿名函数返回的是dynamic,导致类型不兼容。
  2. 不可修改Map报错:orders中的Map可能被隐式转为不可修改实例(比如Dart对字面量Map的优化,或来自不可变数据源),直接修改其键值对会触发权限限制。

解决方案

方案1:修复类型并确保Map可变

  1. 给orders指定明确泛型,消除动态类型问题:
List<Map<String, dynamic>> orders = [];
  1. 修改changeOrder方法,先将目标Map复制为可变实例再修改,替换原列表中的元素:
void changeOrder(int orderIndex, List<Map<String, dynamic>> item) {
  // 复制原Map为可变Map
  var mutableMap = Map.from(orders[orderIndex]);
  mutableMap["order"] = item;
  // 替换列表中的原元素
  orders[orderIndex] = mutableMap;
  notifyListeners();
}

方案2:初始化时直接创建可变Map

在getOrders方法中,用Map.from()包装每个字面量Map,确保它们从一开始就是可变的:

void getOrders(){
  orders = [
    Map.from({
      "id":1,
      "order":[
        {"id":1,"name":"mike"},
        {"id":2,"name":"john"},
        {"id":3,"name":"smith"}
      ]
    }),
    Map.from({
      "id":1,
      "order":[
        {"id":1,"name":"roz"},
        {"id":2,"name":"sam"},
        {"id":3,"name":"ruby"}
      ]
    }),
  ];
  notifyListeners();
}

此时再使用第二种修改方式即可正常工作:

void changeOrder(int orderIndex, List<Map<String, dynamic>> item) {
   orders[orderIndex]["order"] = item;
   notifyListeners();
}

额外提示

页面中生成item的代码var item = List.from(orders[index]);存在逻辑错误,因为orders[index]是一个Map,List.from()会将Map的键值对转为List元素,不符合修改order字段的预期。正确写法应为:

var item = List.from(orders[index]["order"]);

内容的提问来源于stack exchange,提问作者Sarmed MQ Berwari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:24:31