【问题标题】:Flutter return parsing dynamic object from serviceFlutter 从服务返回解析动态对象
【发布时间】:2020-02-20 02:14:15
【问题描述】:

我创建了多个模型并使用 json_serialization

例如公司和员工等等。

import 'package:json_annotation/json_annotation.dart';

part 'company.g.dart';

@JsonSerializable()
class Company {
  Company({this.id, this.name});

  String id;
  String name;


  factory Company.fromJson(Map<String, dynamic> json) => _$CompanyFromJson(json);

  Map<String, dynamic> toJson() => _$CompanyToJson(this);
}
import 'package:json_annotation/json_annotation.dart';

part 'employee.g.dart';

@JsonSerializable()
class Employee {
  Employee({this.id, this.name, this.email, this.phone, this.photo});

  String id;
  String name;
  String email;
  String phone;
  String photo;

  factory Employee.fromJson(Map<String, dynamic> json) => _$EmployeeFromJson(json);

  Map<String, dynamic> toJson() => _$EmployeeToJson(this);
}

现在我想创建一个可重用的服务,它可以返回类型为 Company、Employee 或其他类型的 Stream。 我使用的是 Firebase,所以返回类型是 Map。

示例服务类

class BaseService<T> {
  final String collection;
  CollectionReference _collectionRef;

  FirebaseBase({@required this.collection}) {
    _collectionRef = Firestore.instance.collection(collection);
  }

  Stream<List<T>> find() {
    return inColRef.snapshots().map((list) {
      return list.documents.map((doc) {
        final Map<String, dynamic> data = doc.data;
        data['id'] = doc.documentID;
        return data;
      }).toList();
    });
  }
}

如何将返回数据(地图)转换为类型 Company 或 Employee。

这些类可以使用 fromJson(data) 的工厂。 但我无法返回 T.fromJson(data)。

我想得到

Stream<List<Company>> companies = ServiceBase('companies').find();
Stream<List<Employee>> employees = ServiceBase('employee').find();

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    这是使用当前代码完成通用分配的方式:

    class BaseService<T> {
      final String collection;
      CollectionReference _collectionRef;
    
      FirebaseBase({@required this.collection}) {
        _collectionRef = Firestore.instance.collection(collection);
      }
    
      Stream<List<T>> find() {
        return inColRef.snapshots().map((list) {
          return list.documents.map((doc) {
            final Map<String, dynamic> data = doc.data;
            data['id'] = doc.documentID;
            return _build(data) as T;
          }).toList();
        });
      }
    
      dynamic _build(final Map<String, dynamic> data) {
          if(collection == 'companies') {
             return Company.fromJson(data);
          } else if(collection == 'employee') {
             return Employee.fromJson(data);
          }
          ... throw if invalid collection passed ? ... 
      }
    }
    

    这将被称为:

    Stream<List<Company>> companies = BaseService<Company>('companies').find();
    Stream<List<Employee>> employees = BaseService<Employee>('employee').find();
    

    我建议你应该使用模板方法模式的不同对象结构,例如:

    class CompanyService extends BaseService<Company> {
          CompanyService() : super('companies');
    
          Company build(final Map<String, dynamic> data) => Company.fromJson(data);   
    }
    class EmployeeService extends BaseService<Employee> {
          EmployeeService() : super('employee');
    
          Employee build(final Map<String, dynamic> data) => Employee.fromJson(data);   
    }
    abstract class BaseService<T> {
          final String collection;
          CollectionReference _collectionRef;
          BaseService(this.collection) {
             _collectionRef = Firestore.instance.collection(collection);
          }
    
          T build(final Map<String, dynamic> data);
    
          Stream<List<T>> find() {
            return inColRef.snapshots().map((list) {
               return list.documents.map((doc) {
               final Map<String, dynamic> data = doc.data;
               data['id'] = doc.documentID;
               return build(data);
            }).toList();
        });
          }
    }
    

    这将导致调用代码看起来像这样:

    Stream<List<Company>> companies = CompanyService().find();
    Stream<List<Employee>> employees = EmployeeService().find();
    

    【讨论】:

    • 谢谢布赖恩。您推荐的解决方案会有所帮助。学到了一些新东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    相关资源
    最近更新 更多