【问题标题】:Flutter map.addAll() results in failureFlutter map.addAll() 导致失败
【发布时间】:2018-09-24 18:07:11
【问题描述】:

我在 Flutter 中得到了以下List<Map>

List<Map<String, dynamic>> recipeList = [
  {
'name': 'rec1',
'id': 1,
'img': 'images/recipe.jpg',
'ingredients': [{
  'name': 'salt',
  'amount': '1',
  'unit': '1',
},
{
  'name': 'flour',
  'amount': '100',
  'unit': 'g',
},
{
  'name': 'water',
  'amount': '100',
  'unit': 'g',
},
{
  'name': 'milk',
  'amount': '100',
  'unit': 'g',
},],
},]

我通过几个Widgets 传递它,并且在某些时候我想将键值对{'didBuy':false} 添加到成分列表中的每个Map(基本上是recipeList['ingredients'])。 因此我称之为:

List<Map<String, dynamic>> resultList = recipeList['ingredients'].map((elem) {
  elem.addAll({'didBuy': false});
  print(elem);
}).toList();

很遗憾,出现以下错误消息:Dart Error: Unhandled exception:type '_InternalLinkedHashMap&lt;String, bool&gt;' is not a subtype of type 'Map&lt;String, String&gt;' of 'other'

有没有人知道在地图上添加东西而不收到此错误消息的正确方法是什么?

将问题编辑得更准确。

编辑2: 按照 Hadrien 的建议,在 Map 内显式调用 List 的类型后,我可以使用布尔值添加键值对。长期想从网上获取数据,所以我定义了一个RecipeObj:

class RecipeObj{

  String name;
  int id;
  String img;
  List<Map<String, dynamic>> ingredients;

  RecipeObj(this.name, this.id, this.img, this.ingredients);

}

这里我明确说明了成分属性的类型,所以我想我可以得到(主)recipeList 中的显式调用。但是通过一些widget向下传递成分属性后,flutter识别为List&lt;Map&lt;String, String&gt;&gt;,虽然我到处都定义为List&lt;Map&lt;String, dynamic&gt;&gt;,这是为什么呢?

【问题讨论】:

  • 什么是ingredientsrecipeList 他们应该是一样的吗?
  • 此代码recipeList['ingredients']. 无效。 recipeList 是一个列表,而不是映射,您需要使用整数索引访问元素。也许你的意思是recipeList[0]['ingredients'].

标签: dart flutter


【解决方案1】:

dart 使用 Map&lt;String, String&gt; 推断您的成分列表的类型

您可以在列表中自己指定类型

'ingredients': <Map<String, dynamic>>[ {
  'name': 'salt',
  'amount': '1',
  'unit': '1',
 },

或在您的 map 函数中构建一个新的 Map&lt;String, dynamic&gt;

 List<Map<String, dynamic>> resultList = recipeList['ingredients'].map((elem) {
  final map = Map<String, dynamic>.from(elem);
  map.addAll({'didBuy': false});
  return map;
 }).toList();

【讨论】:

  • 谢谢,在Map 中指定List 的类型就可以了。但由于这个 recipeList 只是虚拟数据,最终会从互联网上获取,我对这种方法不太满意。我编辑了我的问题以反映这一点。
  • 你试过第二种方法了吗?
  • 请注意,一旦您从网络获取数据,您可能不会再出现此错误,jsonDecode 应该会产生Map&lt;String, dynamic&gt;
  • 成功了,谢谢!我还注意到,当您在同一个映射中具有 Stringint 之类的混合值类型时,flutter 始终将其识别为 Map&lt;String, dynamic&gt;,因此添加 bool 没有问题。
【解决方案2】:

应该这样做

List<Map<String,dynamic>> recipeList = [

至少如果recipeListingredients 指向同一个集合实例。

var ingredients = recipeList;

【讨论】:

  • 谢谢,它对我有点帮助,我将它添加到我的代码中,我还更新了我的问题。
【解决方案3】:

这是你需要的吗?

void main() {

List<Map> recipeList = [
  {
'name': 'rec1',
'id': 1,
'img': 'images/recipe.jpg',
'ingredients': [{
  'name': 'salt',
  'amount': '1',
  'unit': '1',
},
{
  'name': 'flour',
  'amount': '100',
  'unit': 'g',
},
{
  'name': 'water',
  'amount': '100',
  'unit': 'g',
},
{
  'name': 'milk',
  'amount': '100',
  'unit': 'g',
},]
},];

  print("[DATA BEFORE ANY CHANGE]");
  print("recipeList.length=${recipeList.length}");
  print("recipeList[0][\"ingredients\"]=${recipeList[0]["ingredients"]}");
  print("recipeList[0][\"ingredients\"].last=${recipeList[0]["ingredients"].last}"); 
  print("recipeList[0][\"ingredients\"].length=${recipeList[0]["ingredients"].length}");

  // no recipe is worth if it doesn't contain chocolate
  recipeList[0]["ingredients"].add({
    'name': 'cocoa powder',
    'amount': '200',
    'unit': 'g',    
  });

  print("\n\n[DATA AFTER ADD]");
  print("recipeList[0][\"ingredients\"].last=${recipeList[0]["ingredients"].last}");
  print("recipeList[0][\"ingredients\"].length=${recipeList[0]["ingredients"].length}");
}

输出

[DATA BEFORE ANY CHANGE]
recipeList.length=1
recipeList[0]["ingredients"]=[{name: salt, amount: 1, unit: 1}, {name: flour, amount: 100, unit: g}, {name: water, amount: 100, unit: g}, {name: milk, amount: 100, unit: g}]
recipeList[0]["ingredients"].last={name: milk, amount: 100, unit: g}
recipeList[0]["ingredients"].length=4


[DATA AFTER ADD]
recipeList[0]["ingredients"].last={name: cocoa powder, amount: 200, unit: g}
recipeList[0]["ingredients"].length=5

【讨论】:

    猜你喜欢
    • 2019-11-07
    • 1970-01-01
    • 2013-12-10
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-21
    • 2020-03-13
    相关资源
    最近更新 更多