【问题标题】:Dart: Can't access to nested map objectDart:无法访问嵌套的地图对象
【发布时间】:2020-03-30 04:33:44
【问题描述】:

我正在创建一个 Flutter 应用程序,但我无法访问 dart 中的嵌套地图对象。 我的代码如下。

 Map<String, String> _localizedValues;

  Future<bool> load() async {
    // Load a language JSON file from the 'i18n' folder
    String value = await rootBundle.loadString('i18n/${locale.languageCode}.json');
    Map<String, dynamic> jsonMap = jsonDecode(value);
    _localizedValues = jsonMap.map((key, value) {
      return MapEntry(key, value.toString());
    });
    return true;
  }

  String translate(String parent, String key) {
    // Returns a localized text
    return _localizedValues[parent][key];
  }

并且出现错误[key]这部分。它说

参数类型“String”不能分配给参数类型“int”。

JSON 文件是这样的。

{
     "Parent": {
         "key": "key"
     }
 }

我有什么问题?

【问题讨论】:

  • [parent][key] 接受int 而不是String 的人之一

标签: flutter dart


【解决方案1】:

我将针对这个问题提出一个不同的解决方案,这可能对您来说更容易使用。 在使用它之前,您可以简单地展平多维 json 对象。

Map<String, String> _localizedValues;

Map flattenTranslations(Map<String, dynamic> json, [String prefix = '']) {
    final Map<String, String> translations = {};
    json.forEach((String key, dynamic value) {
      if (value is Map) {
        translations.addAll(flattenTranslations(value, '$prefix$key.'));
      } else {
        translations['$prefix$key'] = value.toString();
      }
    });
    return translations;
  }

  Future<bool> load() async {
    // Load a language JSON file from the 'i18n' folder
    String value = await rootBundle.loadString('i18n/${locale.languageCode}.json');
    Map<String, dynamic> jsonMap = jsonDecode(value);
    _localizedValues = flattenTranslations(jsonMap);
    return true;
  }

您将获得一个简单的 Map 对象,该对象将包含 json 的所有键,每个子树键都以其父键为前缀。

例如:

    {
  "Parent": {
    "key": "key",
    "key1": "key",
    "key2": "key",
    "key3": "key",
    "someOtherKey": {
      "key213": "keyeye",
      "oneMoreLevel": {
        "key123412": "asdasdasd"
      }
    }
  }
}

将转换为包含“Parent.someOtherKey.oneMoreLevel.key123412”键的地图。 之后你可以使用这个函数来获取翻译:

    String translate(String key) {
    // Returns a localized text or KEY if there's no localization
    return _localizedValues[key] ?? key;
  }

print(translate('Parent.someOtherKey.oneMoreLevel.key123412'));

【讨论】:

  • 嗯,它不起作用。仍然无法访问嵌套对象,它只返回key
  • 当我删除?? key这部分时,错误消息是A non-null String must be provided to a Text Widget.,因此它无法访问我想要获取的值。
  • 这是因为 Text 小部件无法接受要显示的空值。您可以将?? key 更改为?? '',这样它将返回一个空字符串。 ??是一个 null 感知运算符,如果第一个操作数为 NULL,它将返回第二个操作数。
  • 我的意思是这种方式无法访问嵌套值,所以会发生错误。
  • 用您正在使用的新代码更新您的第一篇文章。
【解决方案2】:

查看您的数据格式:

{
     "Parent": {
         "key": "key"
     }
 }

作为一个例子,它应该是这样的:

{"a": {"a": "4"}, "b": {"b": "5"}}

你在这行做什么:MapEntry(key, value.toString()); 是,你正在将内部映射 ({"a": "4"}) 转换为 String。这就是您看到该错误的原因。

尝试从MapEntry(key, value.toString()) 中删除.toString()

如果这不起作用,请告诉我。

【讨论】:

  • @Ooto 你确定数据格式吗?可以分享一下样品吗?
  • 问题真的来自json吗?我想知道因为translate 函数上发生了错误。
【解决方案3】:
_localizedValues = jsonMap.forEach((key, value) {
  return MapEntry(key, value.toString());
});

【讨论】:

  • 如何将void 类型分配给变量?我的意思是这里没有意义
  • 虽然此代码可能会解决问题,但 including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的答案添加解释并说明适用的限制和假设。 From Review
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多