6

我正在尝试为 freezed package 生成的 union 实现 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()},
      );
}

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

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

4

3 回答 3

0

改变toJson(Result object)方法是这样的

 @override
  Map<String, dynamic> toJson(Result object) => object.toJson(); 
于 2021-11-23T02:15:07.130 回答
0

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

另外,它适用于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);
}
于 2021-12-10T17:16:01.193 回答
-2

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

尝试这个:

final result = ResultConverter().fromJson(json);
于 2021-01-14T00:18:47.707 回答