dart 中冻结包生成的联合的 JsonConverter

Posted

技术标签:

【中文标题】dart 中冻结包生成的联合的 JsonConverter【英文标题】:JsonConverter for unions generated by freezed package in dart 【发布时间】:2020-10-07 19:01:15 【问题描述】:

我正在尝试为freezed package 生成的联合实现 toJson/fromJson。假设我们有一个类如下:

@freezed
abstract class Result with _$Result 
  const factory Result.error(String message) = Error;
  const factory Result.success() = Success;

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

我希望/fromJson 的行为如下:

 Result error = Result.error('some error');
 expect(error.toJson(), 'type': 'error', 'message': 'some error');
 expect(Result.fromJson('type': 'error', 'message': 'some error'), error);

文档中说可以使用JsonConverter(fromJSON with multiple classes),但我不知道如何正确使用。

class ResultConverter implements JsonConverter<Result, Map<String, dynamic>> 
  const ResultConverter();

  @override
  Result fromJson(Map<String, dynamic> json) 
    if (json == null) 
      return null;
    
    switch (json['type'] as String) 
      case 'success':
        return Success.fromJson(json);
      case 'error':
        return Error.fromJson(json);

      default:
        throw FallThroughError();
    
  

  @override
  Map<String, dynamic> toJson(Result object) => object.map(
        error: (e) => 'type': 'error', ...e.toJson(),
        success: (s) => 'type': 'success', ...s.toJson(),
      );

如果工厂方法调用ResultConverter().fromJson(this) 而不是生成的方法,fromJson 可以正常工作,但这感觉像是一种解决方法,不适用于 toJson。

是否可以以某种方式注释 Result 类以便代码生成将使用转换器?

【问题讨论】:

【参考方案1】:

toJson(Result object)方法改成那样

 @override
  Map<String, dynamic> toJson(Result object) => object.toJson(); 

【讨论】:

【参考方案2】:

是的,这个资源帮助我 - link 实现了它。

另外,它适用于freezed 包的专用命名构造函数。

像这样(请注意不要添加abstract关键字和private构造函数):

@freezed 
class Result with _$Result 

  const Result._();

  @ResultConverter()
  const factory Result.error(String message) = Error;

  @ResultConverter()
  const factory Result.success() = Success;

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

【讨论】:

【参考方案3】:

你可以只使用你的转换器。

试试这个:

final result = ResultConverter().fromJson(json);

【讨论】:

以上是关于dart 中冻结包生成的联合的 JsonConverter的主要内容,如果未能解决你的问题,请参考以下文章

如何将具有时间戳字段的firestore doc数据转换为通过Freezed dart包生成的数据类?

尝试生成 g.dart 文件时出错

冻结了如何在***模型上分配我自己的 JsonConverter?

Flutter应用冻结并且无法按预期工作

9Flutter 实现 生成二维码

Dart异步编程--Future