Dart使用json_serializable解析到json或从json解析出库类 [英] Dart Parse to/from json a library class using json_serializable

查看:229
本文介绍了Dart使用json_serializable解析到json或从json解析出库类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • 我正在扑朔迷离地使用地理编码器库.
  • 当我得到一个地址时,我想保存在 firebase
    中firestore
    作为用户(对象)的属性,但要做到这一点,我需要
    序列化地址(将其转换为地图).
  • 当前,我正在使用 json_serializable 来解析/映射我的用户类别.
  • 因为Address是地理编码器库中的一类,所以我很难将其解析到地图中/从地图中解析出来,因为这是由json_serializable处理的.
  • I'm working with geocoder library in flutter.
  • When I get an Address I want to save it in firebase
    firestore
    as an user (object) atribute but to do that I need to
    serialize the address (convert it to a map).
  • Currently, I'm using json_serializable to parse from/to map my User class.
  • Because Address is a class from geocoder library I'm having troubles to parse it to/from map because this is handled by json_serializable.

这是我的User类:

    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"不是预期的类型"UserAddress".dart(invalid_cast_new_expr)

    The constructor returns type 'Address' that isn't of expected type 'UserAddress'.dart(invalid_cast_new_expr)

    在命名的构造函数UserAddress.fromJson中:

    in the named constructor 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();
    }
    

    请给我一些选择,以实现与地图之间的解析.

    Please give me some options to achieve parsing to/from map, please.

    推荐答案

    如果我答对了,您想用自己的修饰类.您可以使用 @JsonKey 批注设置(解码)库的 Address 对象的函数.

    If I got you right, you want to decorate library's class with your own. You can use @JsonKey annotation to set functions for (en)decoding library's Address object.

    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}
    

    如您所见,所有嵌套对象都被正确编码.

    As you can see, all nested objects are encoded fine.

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

    UPD: When doing that via inheritence, you'll have to pass all base class' fields to super constructor and to override nested objects fields with @JsonKey annotation:

    @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}
    

    但是在这种情况下,我建议对继承使用合成.

    But I recommend using composition over inheritence in this case.

    这篇关于Dart使用json_serializable解析到json或从json解析出库类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆