我很难使用 dart/flutter 从 json 地图中的嵌套 object 获取数据

I am having a hard time getting data from an nested object in a json map using dart/flutter

如标题所述,我正在尝试使用 json MAP 从嵌套的 object 中提取数据。我希望我描述正确。我是飞镖的新手,并且仍在成长为一名程序员。这是我的模型的代码。

class Device {
 List<DevicesModel> _devices = [];
 Page? _page;
 List<DevicesModel> get devices => _devices;

Device({required devices, required page}) {
 this._devices = devices;
 this._page = page;
}

Device.fromJson(Map<String, dynamic> json) {
   if (json['devices'] != null) {
     _devices = <DevicesModel>[];
     json['devices'].forEach((v) {
       _devices.add(DevicesModel.fromJson(v));
     });
    }
  }
}

class DevicesModel {
  late final String deviceId;
  String? publicId;
  String? companyId;
  late final String company;
  late final String label;
  String? imei;
  String? sim;
  String? mobileProviderId;
  String? mobileProvider;
  String? hologramDeviceId;
  String? hologramLinkId;
  String? firmwareVersionId;
  String? version;
  String? formattedVersion;
  String? deviceTypeId;
  String? deviceType;
  String? ipAddress;
  String? recordInterval;
  String? uploadInterval;
  String? powerMode;
  String? connectivity;
  String? connectivityClass;
  String? usersLastRecordDate;
  String? gmtLastRecordDate;
  String? battery;
  String? batteryPercentage;
  String? batteryClass;
  String? batteryIcon;
  String? signalQuality;
  late final String signalQualityClass;
  String? signalQualityText;
  String? signalQualityIcon;
  String? queuedRecords;
  String? command;
  String? status;
  String? statusClass;
  String? purchaseDate;
  String? warrantyPeriod;
  String? warrantyExpires;
  String? warrantyStatus;
  String? temperatureClass;
  late final String temperatureMetric;
  late final String temperatureImperial;
  String? surgeProtection;
  String? totalProducts;
  Null temperatureLowThreshold;
  Null temperatureHighThreshold;
  Null notes;
  Null importId;
  String? deleted;
  String? createdBy;
  String? lastUpdatedBy;
  Null deletedBy;
  Null dateCreated;
  String? dateModified;
  Null dateDeleted;
  String? scope;
  String? owner;
  late List<Ports> ports;

DevicesModel(
  {required this.deviceId,
  this.publicId,
  this.companyId,
  required this.company,
  required this.label,
  this.imei,
  this.sim,
  this.mobileProviderId,
  this.mobileProvider,
  this.hologramDeviceId,
  this.hologramLinkId,
  this.firmwareVersionId,
  this.version,
  this.formattedVersion,
  this.deviceTypeId,
  this.deviceType,
  this.ipAddress,
  this.recordInterval,
  this.uploadInterval,
  this.powerMode,
  this.connectivity,
  this.connectivityClass,
  this.usersLastRecordDate,
  this.gmtLastRecordDate,
  this.battery,
  this.batteryPercentage,
  this.batteryClass,
  this.batteryIcon,
  this.signalQuality,
  required this.signalQualityClass,
  this.signalQualityText,
  this.signalQualityIcon,
  this.queuedRecords,
  this.command,
  this.status,
  this.statusClass,
  this.purchaseDate,
  this.warrantyPeriod,
  this.warrantyExpires,
  this.warrantyStatus,
  this.temperatureClass,
  required this.temperatureMetric,
  required this.temperatureImperial,
  this.surgeProtection,
  this.totalProducts,
  this.temperatureLowThreshold,
  this.temperatureHighThreshold,
  this.notes,
  this.importId,
  this.deleted,
  this.createdBy,
  this.lastUpdatedBy,
  this.deletedBy,
  this.dateCreated,
  this.dateModified,
  this.dateDeleted,
  this.scope,
  this.owner,
  required this.ports
});

DevicesModel.fromJson(Map<String, dynamic> json) {
  deviceId = json['device_id'];
  publicId = json['public_id'];
  companyId = json['company_id'];
  company = json['company'] ?? 'unknown';
  label = json['label'] ?? 'unknown';
  imei = json['imei'];
  sim = json['sim'];
  mobileProviderId = json['mobile_provider_id'];
  mobileProvider = json['mobile_provider'];
  hologramDeviceId = json['hologram_device_id'];
  hologramLinkId = json['hologram_link_id'];
  firmwareVersionId = json['firmware_version_id'];
  version = json['version'];
  formattedVersion = json['formatted_version'];
  deviceTypeId = json['device_type_id'];
  deviceType = json['device_type'];
  ipAddress = json['ip_address'];
  recordInterval = json['record_interval'];
  uploadInterval = json['upload_interval'];
  powerMode = json['power_mode'];
  connectivity = json['connectivity'];
  connectivityClass = json['connectivity_class'];
  usersLastRecordDate = json['users_last_record_date'];
  gmtLastRecordDate = json['gmt_last_record_date'];
  battery = json['battery'];
  batteryPercentage = json['battery_percentage'];
  batteryClass = json['battery_class'];
  batteryIcon = json['battery_icon'];
  signalQuality = json['signal_quality'];
  signalQualityClass = json['signal_quality_class'];
  signalQualityText = json['signal_quality_text'];
  signalQualityIcon = json['signal_quality_icon'];
  queuedRecords = json['queued_records'];
  command = json['command'];
  status = json['status'];
  statusClass = json['status_class'];
  purchaseDate = json['purchase_date'];
  warrantyPeriod = json['warranty_period'];
  warrantyExpires = json['warranty_expires'];
  warrantyStatus = json['warranty_status'];
  temperatureClass = json['temperature_class'];
  temperatureMetric = json['temperature_metric'] ?? 'n/a';
  temperatureImperial = json['temperature_imperial'] ?? 'n/a';
  surgeProtection = json['surge_protection'];
  totalProducts = json['total_products'];
  temperatureLowThreshold = json['temperature_low_threshold'];
  temperatureHighThreshold = json['temperature_high_threshold'];
  notes = json['notes'];
  importId = json['import_id'];
  deleted = json['deleted'];
  createdBy = json['created_by'];
  lastUpdatedBy = json['last_updated_by'];
  deletedBy = json['deleted_by'];
  dateCreated = json['date_created'];
  dateModified = json['date_modified'];
  dateDeleted = json['date_deleted'];
  scope = json['scope'];
  owner = json['owner'];
  if (json['ports'] != null) {
    ports = <Ports>[];
    json['ports'].forEach((v) {
      ports.add(new Ports.fromJson(v));
    });
   }
  }
 }

 class Ports {
  List<PortsModel> _ports = [];
  List<PortsModel> get ports => _ports;

 Ports({required ports}) {
  this._ports = ports;
 }

 Ports.fromJson(Map<String, dynamic> json) {
  if (json['ports'] != null) {
   _ports = <PortsModel>[];
   json['ports'].forEach((v) {
    _ports.add(PortsModel.fromJson(v));
   });
  }
 }
}

class PortsModel {
 String? devicePortsId;
 String? deviceId;
 String? companyId;
 String? company;
 String? productId;
 late final String productName;
 String? portNumber;
 String? version;
 String? sensorTypeId;
 String? sensorType;
 String? sensorDescription;
 String? imperialSymbol;
 String? metricSymbol;
 String? fillVolumeGallons;
 String? fillVolumeLiters;
 String? totalGallonsCapacity;
 String? totalLitersCapacity;
 String? percentFull;
 String? tankTypeId;
 String? tankType;
 String? slug;
 String? imageUrl;
 String? formula;
 String? reorderYellow;
 String? reorderRed;
 String? deleted;
 Null? createdBy;
 String? lastUpdatedBy;
 Null? deletedBy;
 String? dateCreated;
 String? dateModified;
 Null? dateDeleted;
 String? scope;
 String? owner;

PortsModel(
  {this.devicePortsId,
  this.deviceId,
  this.companyId,
  this.company,
  this.productId,
  required this.productName,
  this.portNumber,
  this.version,
  this.sensorTypeId,
  this.sensorType,
  this.sensorDescription,
  this.imperialSymbol,
  this.metricSymbol,
  this.fillVolumeGallons,
  this.fillVolumeLiters,
  this.totalGallonsCapacity,
  this.totalLitersCapacity,
  this.percentFull,
  this.tankTypeId,
  this.tankType,
  this.slug,
  this.imageUrl,
  this.formula,
  this.reorderYellow,
  this.reorderRed,
  this.deleted,
  this.createdBy,
  this.lastUpdatedBy,
  this.deletedBy,
  this.dateCreated,
  this.dateModified,
  this.dateDeleted,
  this.scope,
  this.owner});

PortsModel.fromJson(Map<String, dynamic> json) {
  devicePortsId = json['device_ports_id'];
  deviceId = json['device_id'];
  companyId = json['company_id'];
  company = json['company'];
  productId = json['product_id'];
  productName = json['product_name'] ?? 'unknown';
  portNumber = json['port_number'];
  version = json['version'];
  sensorTypeId = json['sensor_type_id'];
  sensorType = json['sensor_type'];
  sensorDescription = json['sensor_description'];
  imperialSymbol = json['imperial_symbol'];
  metricSymbol = json['metric_symbol'];
  fillVolumeGallons = json['fill_volume_gallons'];
  fillVolumeLiters = json['fill_volume_liters'];
  totalGallonsCapacity = json['total_gallons_capacity'];
  totalLitersCapacity = json['total_liters_capacity'];
  percentFull = json['percent_full'];
  tankTypeId = json['tank_type_id'];
  tankType = json['tank_type'];
  slug = json['slug'];
  imageUrl = json['image_url'];
  formula = json['formula'];
  reorderYellow = json['reorder_yellow'];
  reorderRed = json['reorder_red'];
  deleted = json['deleted'];
  createdBy = json['created_by'];
  lastUpdatedBy = json['last_updated_by'];
  deletedBy = json['deleted_by'];
  dateCreated = json['date_created'];
  dateModified = json['date_modified'];
  dateDeleted = json['date_deleted'];
  scope = json['scope'];
  owner = json['owner'];
 }
}

class Page {
 int? totalRecords;
 int? pageNum;
 int? pageSize;
 Null? previousPage;
 String? nextPage;
 Null? searchString;

Page(
  {this.totalRecords,
  this.pageNum,
  this.pageSize,
  this.previousPage,
  this.nextPage,
  this.searchString});

Page.fromJson(Map<String, dynamic> json) {
  totalRecords = json['total_records'];
  pageNum = json['page_num'];
  pageSize = json['page_size'];
  previousPage = json['previous_page'];
  nextPage = json['next_page'];
  searchString = json['search_string'];
  }
}

后面是我试图打印出嵌套数据的地方。

import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:gateway_device/controllers/device_controller.dart';
import 'package:gateway_device/flutter_flow/flutter_flow_theme.dart';
import 'package:gateway_device/models/devices_model.dart';
import 'package:gateway_device/routes/route_helper.dart';
import 'package:gateway_device/tank_product/tank_product_widget.dart';
import 'package:get/get.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';

class TankProductComponent extends StatefulWidget {
  TankProductComponent({Key? key}) : super(key: key);

  @override
  State<TankProductComponent> createState() => _TankProductComponent();
}

class _TankProductComponent extends State<TankProductComponent> {
  @override
  Widget build(BuildContext context) {
    return GetBuilder<DeviceController>(builder: (devices) {
      // print(devices);

      return Container(
        height: 514,
        child: ListView.builder(
          physics: AlwaysScrollableScrollPhysics(),
          shrinkWrap: true,
          scrollDirection: Axis.vertical,
          itemCount: 3,
          itemBuilder: (context, position) {
            return _buildPageItem(position, devices.deviceList[position]);
          }),
       );
     });
    }

    Widget _buildPageItem(int index, DevicesModel device) {

      getPorts() {
        var ports = device.ports;
        if (device.ports != [null]) {
          return ports;
        }
      }

      print(getPorts());
    }
   }

我遇到的问题是错误告诉我“LateError(LateInitializationError:字段 'ports' 尚未初始化。)”

我正在努力弄清楚如何成功地做到这一点。请帮忙!提前向您致以诚挚的谢意。

这个错误最有可能是因为:

if (json['ports'] != null) {
    ports = <Ports>[];
    json['ports'].forEach((v) {
      ports.add(new Ports.fromJson(v));
    });
   }
  }

如果 json 响应包含端口,则您正在有条件地初始化模型的端口字段。将代码更改为此可能会解决您的问题:

    ports = <Ports>[];
    if (json['ports'] != null) {
            json['ports'].forEach((v) {
              ports.add(new Ports.fromJson(v));
            });
          }
    }

注意你的字段晚了,但是使用前必须先初始化,条件初始化势必会带来麻烦。另外我建议将相关字段分组到模型中,拥有 100 个字段的模型不是一个好的做法。