在其他 json 对象中获取一个 json 列表对象 Flutter

Get a json List object in other json object Flutter

我的请求发送这个:

{
    "id": 1,
    "name": "Client1",
    "areas": [
      {
        "id": 1,
        "name": "AreaName1",
        "streetAddress": "street1",
        "postalCode": "postal1",
        "city": "city1"
      },
      {
        "id": 2,
        "name": "AreaName2",
        "streetAddress": "street2",
        "postalCode": "postal2",
        "city": "city2"
      },
      {
        "id": 3,
        "name": "AreaName3",
        "streetAddress": "street3",
        "postalCode": "postal3",
        "city": "city3"
      },
      {
        "id": 4,
        "name": "AreaName4",
        "streetAddress": "street4",
        "postalCode": "postal4",
        "city": "city4"
      },
      {
        "id": 5,
        "name": "AreaName5",
        "streetAddress": "street5",
        "postalCode": "postal5",
        "city": "city5"
      }
    ]
  },

所以这是一个有区域列表的客户端。

所以我创建了 dto class :

客户端列表DTO:


class ClientListDto {
  int id;
  String pictureUrl;
  String name;
  List<AreaDto> areas;

  ClientListDto({this.id, this.name, this.areas, this.pictureUrl});

  ClientListDto.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    pictureUrl = json['pictureUrl'];
    name = json['name'];
    if (json['areas'] != null) {
      areas = new List<AreaDto>();
      json['areas'].forEach((v) {
        areas.add(AreaDto.fromJson(v));
      });
    }
  }
}

区域DTO :

class AreaDto {
  int id;
  String name;
  String streetAddress;
  String postalCode;
  String city;

  AreaDto({this.id, this.name, this.streetAddress, this.postalCode, this.city});

  static AreaDto fromJson(Map<String, dynamic> json) {
    return AreaDto(
        id: json['id'],
        name: json['name'],
        streetAddress: json['streetAddress'],
        postalCode: json['postalCode'],
        city: json['city']);
  }
}

我的模特:

class Client {
  int id;
  String name;
  String pictureUrl;
  List<Area> areas;

  Client({this.id, this.name, this.pictureUrl, this.areas});

  static Client fromDTO(ClientListDto dto) {
    return Client(
      id: dto.id,
        name : dto.name,
        pictureUrl: dto.pictureUrl,
areas : new List<Area>(),
    );
  }

//  TODO: DEFINE DTO
}

class Area {
  String name;
  String streetAddress;
  String postalCode;
  String city;

  Area({this.name, this.streetAddress, this.postalCode, this.city});

  static Area fromDTO(AreaDto dto) {
    return Area(
        name : dto.name,
        streetAddress: dto.streetAddress,
        postalCode: dto.postalCode,
        city: dto.city
    );
  }
}

我的存储库和我的服务:

  @override
  Future<List<Client>> getListTest() async {
    final mymissionService = MyMissionService.create();
    final token = await accessTokenRepository.getAccessToken();
    print("Token $token");
    final response = await mymissionService.getClient("Bearer ${token}");
    final body = response.body as List<dynamic>;
    final employees = body.map((e) => ClientListDto.fromJson(e)).toList();
    final result = employees
        .map(
          (e) => new Client(
        id: e.id,
        name: e.name,
        pictureUrl: e.pictureUrl,
      ),
    )
        .toList();
    return result;
  }

但是,当我收集我的客户列表时,我如何才能在我的存储库中获取我的区域列表? 如果我只打印这部分,我会正确收集客户而不是我的区域

您可以复制粘贴 运行 下面的完整代码
您可以使用 clientFromJson(jsonString); 进行解析,您可以查看详细的完整代码 ClientArea 定义
并显示嵌套 ListView

代码片段

List<Client> clientFromJson(String str) =>
List<Client>.from(json.decode(str).map((x) => Client.fromJson(x)));
...
if (response.statusCode == 200) {
  return clientFromJson(jsonString);

工作演示

完整代码

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

List<Client> clientFromJson(String str) =>
    List<Client>.from(json.decode(str).map((x) => Client.fromJson(x)));

String clientToJson(List<Client> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Client {
  Client({
    this.id,
    this.name,
    this.areas,
  });

  int id;
  String name;
  List<Area> areas;

  factory Client.fromJson(Map<String, dynamic> json) => Client(
        id: json["id"],
        name: json["name"],
        areas: List<Area>.from(json["areas"].map((x) => Area.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "areas": List<dynamic>.from(areas.map((x) => x.toJson())),
      };
}

class Area {
  Area({
    this.id,
    this.name,
    this.streetAddress,
    this.postalCode,
    this.city,
  });

  int id;
  String name;
  String streetAddress;
  String postalCode;
  String city;

  factory Area.fromJson(Map<String, dynamic> json) => Area(
        id: json["id"],
        name: json["name"],
        streetAddress: json["streetAddress"],
        postalCode: json["postalCode"],
        city: json["city"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "streetAddress": streetAddress,
        "postalCode": postalCode,
        "city": city,
      };
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Future<List<Client>> _future;

  Future<List<Client>> getListTest() async {
    String jsonString = '''
    [{
    "id": 1,
    "name": "Client1",
    "areas": [
      {
        "id": 1,
        "name": "AreaName1",
        "streetAddress": "street1",
        "postalCode": "postal1",
        "city": "city1"
      },
      {
        "id": 2,
        "name": "AreaName2",
        "streetAddress": "street2",
        "postalCode": "postal2",
        "city": "city2"
      },
      {
        "id": 3,
        "name": "AreaName3",
        "streetAddress": "street3",
        "postalCode": "postal3",
        "city": "city3"
      },
      {
        "id": 4,
        "name": "AreaName4",
        "streetAddress": "street4",
        "postalCode": "postal4",
        "city": "city4"
      },
      {
        "id": 5,
        "name": "AreaName5",
        "streetAddress": "street5",
        "postalCode": "postal5",
        "city": "city5"
      }
    ]
  },
  {
    "id": 2,
    "name": "Client2",
    "areas": [
      {
        "id": 21,
        "name": "AreaName1",
        "streetAddress": "street1",
        "postalCode": "postal1",
        "city": "city1"
      },
      {
        "id": 22,
        "name": "AreaName2",
        "streetAddress": "street2",
        "postalCode": "postal2",
        "city": "city2"
      },
      {
        "id": 23,
        "name": "AreaName3",
        "streetAddress": "street3",
        "postalCode": "postal3",
        "city": "city3"
      },
      {
        "id": 24,
        "name": "AreaName4",
        "streetAddress": "street4",
        "postalCode": "postal4",
        "city": "city4"
      },
      {
        "id": 25,
        "name": "AreaName5",
        "streetAddress": "street5",
        "postalCode": "postal5",
        "city": "city5"
      }
    ]
  }
  ]
    ''';

    var response = http.Response(jsonString, 200);

    if (response.statusCode == 200) {
      return clientFromJson(jsonString);
    } else {
      print(response.statusCode);
    }
  }

  @override
  void initState() {
    _future = getListTest();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: FutureBuilder(
            future: _future,
            builder: (context, AsyncSnapshot<List<Client>> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                  return Text('none');
                case ConnectionState.waiting:
                  return Center(child: CircularProgressIndicator());
                case ConnectionState.active:
                  return Text('');
                case ConnectionState.done:
                  if (snapshot.hasError) {
                    return Text(
                      '${snapshot.error}',
                      style: TextStyle(color: Colors.red),
                    );
                  } else {
                    return ListView.separated(
                        separatorBuilder: (BuildContext context, int index) {
                          return SizedBox(
                            height: 10,
                          );
                        },
                        shrinkWrap: true,
                        itemCount: snapshot.data.length,
                        itemBuilder: (context, index) {
                          return Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: <Widget>[
                              Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  crossAxisAlignment: CrossAxisAlignment.center,
                                  children: <Widget>[
                                    Expanded(
                                        flex: 1,
                                        child: Text(snapshot.data[index].name)),
                                    Expanded(
                                      flex: 5,
                                      child: Container(
                                        //height: 50,
                                        child: ListView.separated(
                                            separatorBuilder:
                                                (BuildContext context,
                                                    int index) {
                                              return SizedBox(
                                                width: 10,
                                              );
                                            },
                                            shrinkWrap: true,
                                            scrollDirection: Axis.vertical,
                                            itemCount: snapshot
                                                .data[index].areas.length,
                                            itemBuilder: (context, index1) {
                                              return Row(
                                                  mainAxisAlignment:
                                                      MainAxisAlignment.center,
                                                  crossAxisAlignment:
                                                      CrossAxisAlignment.center,
                                                  children: <Widget>[
                                                    Container(
                                                      width: 120,
                                                      child: Column(
                                                        children: <Widget>[
                                                          Text(
                                                            snapshot
                                                                .data[index]
                                                                .areas[index1]
                                                                .name,
                                                            style: TextStyle(
                                                                color:
                                                                    Colors.red),
                                                          ),
                                                          Text(
                                                              snapshot
                                                                  .data[index]
                                                                  .areas[index1]
                                                                  .id.toString(),
                                                              style: TextStyle(
                                                                  color: Colors
                                                                      .red)),
                                                        ],
                                                      ),
                                                    )
                                                  ]);
                                            }),
                                      ),
                                    )
                                  ])
                            ],
                          );
                        });
                  }
              }
            }));
  }
}