【问题标题】:Dart Parse to/from json a library class using json_serializableDart Parse to/from json 使用 json_serializable 的库类
【发布时间】:2019-11-22 22:42:19
【问题描述】:
  • 我正在与 geocoder library 合作。
  • 当我收到 Address 时,我想将其作为用户(对象)属性保存在 firebase
    firestore
    中,但我需要这样做
    序列化地址(将其转换为地图)。
  • 目前,我使用json_serializable 解析/映射我的 用户类。
  • 由于 Address 是地理编码器库中的一个类,因此我无法将其解析到地图或从地图解析,因为这是由 json_serializable 处理的。

这是我的用户类:

    import 'package:geocoder/model.dart';
    import 'package:json_annotation/json_annotation.dart';

    import './resource.dart';

    part 'user.g.dart';

    @JsonSerializable()
    class User extends Resource {
       User(this.email, this.name);

       String email;
       String name;
       List<Address> addresses;

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

       Map<String, dynamic> toJson() => _$UserToJson(this);
    }
  • 我尝试创建一个名为 UserAddress 的新类,其父类将是 Address 如下所示,但出现错误

构造函数返回的“地址”类型不是预期的“用户地址”类型。dart(invalid_cast_new_expr)

在命名构造函数 UserAddress.fromJson:

import 'package:geocoder/geocoder.dart';
import 'package:json_annotation/json_annotation.dart';

part 'user-address.g.dart';

@JsonSerializable()
class UserAddress extends Address {
  UserAddress();

  factory UserAddress.fromJson(Map<String, dynamic> json) =>
      Address.fromMap(json);

  Map<String, dynamic> toJson() => this.toMap();
}

请给我一些选项来实现对地图的解析。

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    如果我没听错的话,你想用你自己的来装饰图书馆的班级。您可以使用@JsonKey 注解为(en)解码库的Address 对象设置函数。

    import 'dart:convert';
    
    import 'package:geocoder/geocoder.dart';
    import 'package:json_annotation/json_annotation.dart';
    
    part 'user_address.g.dart';
    
    @JsonSerializable()
    class UserAddress {
      UserAddress(this.address, this.oneMoreField);
    
      @JsonKey(fromJson: _addressFromJson, toJson: _addressToJson)
      final Address address;
      final int oneMoreField;
    
      factory UserAddress.fromJson(Map<String, dynamic> json) => _$UserAddressFromJson(json);
      Map<String, dynamic> toJson() => _$UserAddressToJson(this);
    }
    
    String _addressToJson(Address address) => jsonEncode(address.toMap());
    Address _addressFromJson(String json) => Address.fromMap(jsonDecode(json));
    

    示例用法:

    final testUserAddress = UserAddress(Address(
      addressLine: 'test',
      coordinates: Coordinates(10, 20)
    ), 1);
    
    final json = testUserAddress.toJson();
    print(json);
    
    final decoded = UserAddress.fromJson(json);
    

    打印:

    {address: {"coordinates":{"latitude":10.0,"longitude":20.0},"addressLine":"test","countryName":null,"countryCode":null,"featureName":null,"postalCode":null,"locality":null,"subLocality":null,"adminArea":null,"subAdminArea":null,"thoroughfare":null,"subThoroughfare":null}, oneMoreField: 1}
    

    如您所见,所有嵌套对象都编码良好。

    UPD:通过继承执行此操作时,您必须将所有基类的字段传递给超级构造函数并使用 @JsonKey 注释覆盖嵌套对象字段:

    @JsonSerializable()
    class UserAddress extends Address {
      UserAddress({String addressLine, String countryName, this.coordinates, this.oneMoreField}) 
        : super(addressLine: addressLine, countryName: countryName);
    
      @override
      @JsonKey(fromJson: _coordinatesFromJson, toJson: _coordinatesToJson)
      final Coordinates coordinates;
    
      final int oneMoreField;
    
      factory UserAddress.fromJson(Map<String, dynamic> json) => _$UserAddressFromJson(json);
      Map<String, dynamic> toJson() => _$UserAddressToJson(this);
    }
    
    String _coordinatesToJson(Coordinates coordinates) => jsonEncode(coordinates.toMap());
    Coordinates _coordinatesFromJson(String json) => Coordinates.fromMap(jsonDecode(json));
    

    结果:

    {addressLine: test, countryName: null, coordinates: {"latitude":10.0,"longitude":20.0}, oneMoreField: 1}
    

    但我建议在这种情况下使用组合而不是继承。

    【讨论】:

    • 由于UserAddress扩展了Address以实现将UserAddress直接解析为Address的解决方案,因此答案是否可以通过删除UserAddress中的属性Address来实现?
    猜你喜欢
    • 2022-12-26
    • 2019-10-09
    • 1970-01-01
    • 2020-08-15
    • 2019-08-16
    • 2019-06-07
    • 2019-08-23
    • 2021-11-12
    • 2013-03-23
    相关资源
    最近更新 更多