Dart 解析到 json 一个使用 json_serializable 的库类


  • 我正在使用颤振中的地理编码器库。
  • 当我得到一个地址时,我想将其作为用户(对象(贡品保存在Firebase
    firestore中,但要做到这一点,我需要
    序列化地址(将其转换为地图(。
  • 目前,我正在使用json_serializable来解析我的 用户类。
  • 由于地址是地理编码器库中的一个类,因此我无法将其解析为地图/从地图解析,因为这是由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的新类,其父类将是地址,如下所示,但是我收到错误

构造函数返回的类型"地址"不是预期类型"用户地址".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();
}

请给我一些选项来实现解析到/从地图解析。

如果我猜对了,你想用你自己的来装饰图书馆的班级。您可以使用@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}

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

相关内容