【问题标题】:Use dart json_serializable to map an object field to JSON flat keys (one to many mapping)使用 dart json_serializable 将对象字段映射到 JSON 平面键(一对多映射)
【发布时间】:2021-12-20 18:41:54
【问题描述】:

我有一个包含Money 类型字段的飞镖对象,它本身由amountcurrency 组成:

@JsonSerializable()
class Account {

  final String id;
  final String type;
  final String subtype;
  final String origin;
  final String name;
  final String status;
  final String currency;
  final Money balance; <== value object
  ...
}

Money 看起来像这样:

class Money {
  final int amount;
  final String currency;

  const Money(this.amount, this.currency);
  ...
}

上面是映射给sqflite使用的,因此目标JSON必须是一个平面JSON,比如:

{
  "id": String,
  "type": String,
  "subtype": String,
  "origin": String,
  "name": String,
  "status": String,
  "currency": String,
  "balanceAmount": int;      <== value object
  "balanceCurrency": String; <== value object
}

我知道我可以在解码之前使用JsonKey.readValue 从整个 JSON 对象中提取复合对象。

但我怎么能反其道而行之呢?从Money 实例中获取两个值并将它们映射到balanceAmountbalanceCurrency?

我在json_serializable api 文档、GitHub 问题或 StackOverflow 上所做的搜索似乎没有特别回应这一点:如何将一个字段映射到两个(或更多)目标键?

【问题讨论】:

    标签: dart json-serializable


    【解决方案1】:

    如果生成的代码在"balance"中使用完整的json,这个解决方案会更好 像这样:

    Money.fromJson(json)

    但我不知道该怎么做:(

    import 'package:project/test/money.dart';
    import 'package:json_annotation/json_annotation.dart';
    
    part 'account.g.dart';
    
    @JsonSerializable()
    class Account {
      final String id;
      final String type;
      final String subtype;
      final String origin;
      final String name;
      final String status;
      final String currency;
      @JsonKey(fromJson: _dataFromJson)
      final Money balance; // <== value object
    
      Account({
        required this.id,
        required this.type,
        required this.subtype,
        required this.origin,
        required this.name,
        required this.status,
        required this.currency,
        required this.balance,
      });
    
      static Money _dataFromJson(Object json) {
        if (json is Map<String, dynamic>) {
          return Money(amount: json["balanceAmount"], currency: json["balanceCurrency"]);
        }
    
        throw ArgumentError.value(
          json,
          'json',
          'Cannot convert the provided data.',
        );
        // return Money(amount: 0, currency:"");
      }
    
      factory Account.fromJson(Map<String, dynamic> json) => Account(
            id: json['id'] as String,
            type: json['type'] as String,
            subtype: json['subtype'] as String,
            origin: json['origin'] as String,
            name: json['name'] as String,
            status: json['status'] as String,
            currency: json['currency'] as String,
            balance: Money.fromJson(json),
          );
      Map<String, dynamic> toJson() => _$AccountToJson(this);
    }
    
    // {
    //   "id": String,
    //   "type": String,
    //   "subtype": String,
    //   "origin": String,
    //   "name": String,
    //   "status": String,
    //   "currency": String,
    //   "balanceAmount": int;      <== value object
    //   "balanceCurrency": String; <== value object
    // }
    

    【讨论】:

      猜你喜欢
      • 2019-05-27
      • 2016-06-24
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多