使用 dart json_serialized 将对象字段映射到 JSON 平面键(一对多映射)

lfr*_*ire 6 dart json-serializable

我有一个 dart 对象,其中包含一个类型为 的字段,该字段本身由和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
  ...
}
Run Code Online (Sandbox Code Playgroud)

Money看起来像这样:

class Money {
  final int amount;
  final String currency;

  const Money(this.amount, this.currency);
  ...
}
Run Code Online (Sandbox Code Playgroud)

上面的内容将被映射以供使用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
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

小智 0

如果生成的代码使用完整的 json,这个解决方案会更好,"balance" 如下所示:

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
// }
Run Code Online (Sandbox Code Playgroud)