如何从 class 中列出 class 需要来自多个数据库的数据?

How to make a list from a class that the class need data from several database?

我在从 class 加载列表时遇到问题,class 需要来自多个数据库的数据

数据库:

一个。用户数据(_id,名称,phone)

乙。婚姻状况 (_id, userID, mariageStatus)

--> 用户数据中的“_id”和婚姻状态中的“userID”是要匹配的东西

读取用户数据:

class User {
  final String idUser,
      name,
      phone;

  User(
      {this.idUser,
      this.name,
      this.phone});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
        idUser: json['_id'],
        name: json['name'],
        phone: json['phone']);
  }
}

List<User> userFromJson(jsonData) {
  List<User> result =
      List<User>.from(jsonData.map((item) => User.fromJson(item)));

  return result;
}

// index
Future<List<User>> fetchUser() async {
  String route = AppConfig.API_ENDPOINT + "userdata";
  final response = await http.get(route);
  if (response.statusCode == 200) {
    var jsonResp = json.decode(response.body);
    
    return userFromJson(jsonResp);
  } else {
    throw Exception('Failed load $route, status : ${response.statusCode}');
  }
}

同时阅读婚姻:

class Marriage{
  final String idUser, mariageStatus;

  Marriage(
      {this.idUser,
      this.mariageStatus});

  factory Marriage.fromJson(Map<String, dynamic> json) {
    return Marriage(
        idUser: json['userID'],
        name: json['mariageStatus']);
  }
}

List<Marriage> marriageFromJson(jsonData) {
  List<Marriage> result =
      List<Marriage>.from(jsonData.map((item) => Marriage.fromJson(item)));

  return result;
}

// index
Future<List<Marriage>> fetchMarriage() async {
  String route = AppConfig.API_ENDPOINT + "marriage";
  final response = await http.get(route);
  if (response.statusCode == 200) {
    var jsonResp = json.decode(response.body);
    
    return marriageFromJson(jsonResp);
  } else {
    throw Exception('Failed load $route, status : ${response.statusCode}');
  }
}

那么如何制作这样的组合 class 列表?

class User_Mariage {
  final String idUser,
      name,
      phone,
      mariageStatus;

  User(
      {this.idUser,
      this.name,
      this.phone,
      this.mariageStatus});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
        idUser: 
        name: 
        phone: 
        mariageStatus: 
  }
}

List<User> userFromJson(jsonData) {
  List<User> result =
      List<User>.from(jsonData.map((item) => User.fromJson(item)));

  return result;
}

如果有其他更好的列单方法,请告诉我,非常感谢

对我来说,您似乎使用了错误的数据库查询。 也许有可能使用外键(userId)。

合并数据的方法有多种。

这是一个示例,您可以通过引用合并 classes 并使用 getter

您的原始用户 class:

import 'dart:convert';

class User {
  final String id, name, phone;

  User({
    required this.id,
    required this.name,
    required this.phone,
  });

  factory User.fromJson(Map<String, dynamic> json) {
    return User(id: json['_id'], name: json['name'], phone: json['phone']);
  }
}

List<User> userFromJson(dynamic jsonData) {
  return List<User>.from(jsonData.map((item) => User.fromJson(item)));
}

Future<List<User>> fetchUser() async {
  String route = AppConfig.API_ENDPOINT + "userdata";
  final response = await http.get(route);
  if (response.statusCode == 200) {
    var jsonResp = json.decode(response.body);
    return userFromJson(jsonResp);
  } else {
    throw Exception('Failed load $route, status : ${response.statusCode}');
  }
}

你原来的 Mariage class

import 'dart:convert';

class Marriage {
  final String idUser, mariageStatus;

  Marriage({required this.idUser, required this.mariageStatus});

  factory Marriage.fromJson(Map<String, dynamic> json) {
    return Marriage(
        idUser: json['userID'], mariageStatus: json['mariageStatus']);
  }
}

List<Marriage> marriageFromJson(dynamic jsonData) {
  return List<Marriage>.from(jsonData.map((item) => Marriage.fromJson(item)));
}

// index
Future<List<Marriage>> fetchMarriage() async {
  String route = AppConfig.API_ENDPOINT + "marriage";
  final response = await http.get(route);
  if (response.statusCode == 200) {
  var jsonResp = json.decode(response.body);
    //'[{"_id":"6194a2e65c504crb1d9af81d","userID":"6782452bd2ab63488c9f2663","mariageStatus":"Single"},{"_id":"6194a2959c534c01ft9rf24c","userID":"6785p58b41894b50b22db401","mariageStatus":"Married"}]'
  return marriageFromJson(jsonResp);
  } else {
    throw Exception('Failed load $route, status : ${response.statusCode}');
  }
}

A UserWithMariageStatus class,这将占用 User 和 Mariage Reference:

import 'package:flutter_fetch_data/mariage.dart';
import 'package:flutter_fetch_data/user.dart';

class UserWithMariageStatus {
  final User user;
  final Marriage mariage;

  UserWithMariageStatus(this.user, this.mariage);

  String get userId => user.id;
  String get name => user.name;
  String get phone => user.phone;
  String get mariageStatus => mariage.mariageStatus;
}

List<UserWithMariageStatus> combineUserWithMarriageStatus(
    List<User> user, List<Marriage> userMariage) {
  List<UserWithMariageStatus> result = [];
  // if userId is unique, iterate the lists and combine
  for (var item in userMariage) {
    result.add(UserWithMariageStatus(
        user.singleWhere((element) => element.id == item.idUser), item));
  }
  return result;
}

在你的 fetch 调用函数中使用它:

import 'package:flutter_fetch_data/mariage.dart';
import 'package:flutter_fetch_data/user.dart';
import 'package:flutter_fetch_data/user_with_mariage.dart';

void main(List<String> args) async {
  List<User> userList = await fetchUser();

  for (var user in userList) {
    print("id: ${user.id}, name: ${user.name}, phone: ${user.phone}");
  }

  List<Marriage> mariageList = await fetchMarriage();
  for (var mariage in mariageList) {
    print("id: ${mariage.idUser}, mariageStatus: ${mariage.mariageStatus}");
  }

  List<UserWithMariageStatus> userWithMariageList =
      combineUserWithMarriageStatus(userList, mariageList);
  for (var userWithMariage in userWithMariageList) {
    print(
        "id: ${userWithMariage.userId}, name: ${userWithMariage.name}, phone: ${userWithMariage.phone}, mariageStatus: ${userWithMariage.mariageStatus}");
  }
}

在 FutureBuilder 中,您可以这样使用它:

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Future<List<UserWithMariageStatus>>? getUserWithMarriageList() async {
    final user = await fetchUser();
    final marriage = await fetchMarriage();
    return combineUserWithMarriageStatus(user, marriage);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Test Fetch Future",
      home: Scaffold(
        body: FutureBuilder<List<UserWithMariageStatus>>(
          future: getUserWithMarriageList(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return ListView(
                  children: snapshot.data!
                      .map((e) => ListTile(
                          title: Text(
                              "id: ${e.userId}, name: ${e.name}, phone: ${e.phone}, marriage: ${e.mariageStatus}")))
                      .toList());
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}