如何为json可序列化对象设置默认值?

flu*_*ter 7 dart flutter

我想设置一个默认值AvailableService。对于原语来说它足够简单。我将如何使用自定义对象来做到这一点

class Submenu extends Equatable {
     @JsonKey(defaultValue: "")
        final String name;
      @JsonKey(defaultValue: new AvailableService(false,false,false,false))
        final AvailableService availableService;
    
    }
Run Code Online (Sandbox Code Playgroud)

自定义对象:

AvailableService {
bool supportsDelivery;
  bool supportsTableService;
  bool supportsCollection;
  bool supportsChat;
 
}
Run Code Online (Sandbox Code Playgroud)

编译时错误是

Arguments of a constant creation must be constant expressions.
Try making the argument a valid constant, or use 'new' to call the constructor
Run Code Online (Sandbox Code Playgroud)

Mab*_*ten 11

一般来说,作为注释参数,您只能传递常量,因此您不能传递使用 new 创建的对象,而只能使用 const 构造函数(您应该将所有可用服务字段定义为final,并定义一个 const 构造函数)。然而,在 json_Serialized 中,defaultValue 目前有一些额外的限制:

  • 您甚至不能使用使用const 构造函数创建的自定义对象(或者您会收到错误“它必须是文字”)。有一个删除此约束的公开请求:#741 - Const as default value
  • 作为 defaultValue,仅允许使用文字;然后,您可以传递Map 文字(即:@JsonKey(defaultValue: {"supportsDelivery" : false, "supportsTableService" : false, /* etc */})),但即使这种可能性目前也仅适用于具有 Map 类型的字段的默认值,而不适用于具有自定义类型的字段(如可用服务)。在这种情况下,您不会收到错误,但永远不会使用 defaultValue(通过查看 .g.dart 文件中生成的代码,您可以理解原因)。对于此问题也有开放请求:#676 - 允许默认值编码为 JSON#789 - 如何为嵌套 JSON 对象设置默认值?

因此,目前,在跟进上述请求之前,我找到的唯一解决方法是在工厂中处理 defaultValue fromJson()

  factory AvailableService.fromJson(Map<String, dynamic> json) =>
      json != null 
      ? _$AvailableServiceFromJson(json)
      : AvailableService(false, false, false, false);
Run Code Online (Sandbox Code Playgroud)

简而言之,JsonKey.defaultValue目前仅支持文字- 甚至不接受常量 - 并且只能用于原始类型字段(或 List、Map、Set)的默认值。


Pav*_*vel 6

从json_serialized 5开始,生成的fromJson使用构造函数中的默认参数,所以你可以这样做

@JsonSerializable()
class Cart {
  final List<int> items;

  const Cart({
    this.items = const [],
  });

  factory Cart.fromJson(Map<String, dynamic> json) => _$CartFromJson(json);

  Map<String, dynamic> toJson() => _$CartToJson(this);
}

@JsonSerializable()
class User {
  final Cart cart;

  const User({
    this.cart = const Cart(),
  });

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  Map<String, dynamic> toJson() => _$UserToJson(this);
}
Run Code Online (Sandbox Code Playgroud)

然后Cart.fromJson({}).items或者User.fromJson({}).cart.items会给你[]