flutter - Dart 使用 json_serializable 解析到/从 json 库类

标签 flutter dart

  • 我正在与 geocoder library 一起工作在 flutter 。
  • 当我收到 Address我想保存在firebase
    firestore
    作为用户(对象)属性,但要做到这一点,我需要
    序列化地址(将其转换为 map )。
  • 目前,我正在使用 json_serializable解析/映射我的
    用户类。
  • 因为地址是地理编码器库中的一个类,所以我在将其解析为 map 或从 map 解析它时遇到了麻烦,因为这是由 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 的新类,其父类将是如下地址,但我收到错误

  • The constructor returns type 'Address' that isn't of expected type '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();
    }
    

    请给我一些选项来实现解析到/从 map ,拜托。

    最佳答案

    如果我猜对了,你想用你自己的类来装饰图书馆的类。您可以使用 @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 :当通过继承这样做时,您必须将所有基类的字段传递给 super 构造函数,并使用 @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}
    

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

    关于flutter - Dart 使用 json_serializable 解析到/从 json 库类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59002699/

    相关文章:

    dart - Flutter MethodChannel嵌套值: 'List<dynamic>' is not a subtype of type 'FutureOr<List<Map<String, double>>>'

    date - 如何使用Firestore仅从特定日期获取数据?

    flutter - 如何在(Flutter)中仅将新值存储到sqflite数据表

    Flutter 热重载不适用于 VSCode 中的自动保存

    Flutter 富内容本地化

    android - Flutter - 使用视频播放器发送标题

    android - 键盘打开/关闭后 Flutter 重建

    flutter - 如何用 flutter 制作小部件的一侧圆形边框?

    android - 构建发布失败 Flutter

    flutter - 如何在Flutter的 future 中使用 future ?