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

Flutter动态键JSON解码问题:仅获首个键值对的排查

问题分析
  1. 仅获取第一个键值对的原因:
    • ProductLineEntity.fromJson中使用json.keys.first只读取了第一个产品线键,直接忽略了其他键值对。
    • readJson方法将包含所有产品线的单个Map对象直接传入ProductLineEntity.fromJson,没有遍历Map中的所有产品线条目。
  2. 未设置ProductCodeEntity的productLineName:解析产品代码时,没有将所属产品线名称传递给对应的实体类字段。
修正后的代码

1. 核心修正:readJson方法

遍历JSON中的所有产品线条目,逐个生成ProductLineEntity,同时为每个ProductCodeEntity设置所属产品线名称:

Future<List<ProductLineEntity>> readJson() async {
  try {
    final String jsonData = await rootBundle.loadString('assets/part_numbers2.json');
    // 解析JSON,取出包含所有产品线的Map
    final Map<String, dynamic> productLinesMap = (json.decode(jsonData) as List<dynamic>).first;
    
    List<ProductLineEntity> productLines = [];
    // 遍历所有产品线键值对
    productLinesMap.forEach((lineName, productCodesJson) {
      // 解析当前产品线的所有产品代码,并绑定产品线名称
      List<ProductCodeEntity> codeList = (productCodesJson as List<dynamic>)
          .map((codeJson) => ProductCodeEntity.fromJson(codeJson)..productLineName = lineName)
          .toList();
      
      productLines.add(ProductLineEntity(
        name: lineName,
        productCodeList: codeList,
      ));
    });
    
    return productLines;
  } catch (error) {
    throw Exception('ProductLineEntity, Unexpected error reading JSON: $error');
  }
}

2. 可选优化:调整ProductCodeEntity的fromJson方法

如果想在解析时直接传入产品线名称,可修改fromJson增加参数,让逻辑更清晰:

class ProductCodeEntity {
  int? id;
  String? partNumber;
  bool? orderable;
  String? description;
  String? productLineName;

  ProductCodeEntity({
    this.id,
    this.partNumber,
    this.orderable,
    this.description,
    this.productLineName,
  });

  // 新增参数接收产品线名称
  factory ProductCodeEntity.fromJson(Map<String, dynamic> json, {String? productLineName}) {
    return ProductCodeEntity(
      id: (json['id'] as num?)?.toInt(),
      partNumber: json['partNumber'] as String?,
      orderable: json['orderable'] as bool?,
      description: json['description'] as String?,
      productLineName: productLineName,
    );
  }
}

此时readJson中的代码解析部分需改为:

List<ProductCodeEntity> codeList = (productCodesJson as List<dynamic>)
    .map((codeJson) => ProductCodeEntity.fromJson(codeJson, productLineName: lineName))
    .toList();

3. 简化ProductLineEntity.fromJson(可选)

由于readJson已直接处理实体创建,可删除原fromJson方法,或调整为更贴合场景的形式:

class ProductLineEntity {
  int? id;
  String? name;
  List<ProductCodeEntity>? productCodeList;

  ProductLineEntity({
    this.id,
    this.name,
    this.productCodeList,
  });

  // 可选:直接通过产品线名称和代码列表创建实体
  factory ProductLineEntity.fromLine(String lineName, List<dynamic> codesJson) {
    List<ProductCodeEntity> codeList = codesJson
        .map((codeJson) => ProductCodeEntity.fromJson(codeJson, productLineName: lineName))
        .toList();
    return ProductLineEntity(name: lineName, productCodeList: codeList);
  }
}
验证效果

修正后,readJson会遍历所有产品线键值对,生成完整的ProductLineEntity列表,且每个ProductCodeEntity都会正确带上所属的产品线名称,彻底解决仅获取第一个键值对的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:00:15