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

Nag*_*ual 3 jsonserializer flutter jsonconvert freezed

我冻结了模型(简化):

part 'initial_data_model.freezed.dart';
part 'initial_data_model.g.dart';

@freezed
class InitialDataModel with _$InitialDataModel {
  const factory InitialDataModel() = Data;

  const factory InitialDataModel.loading() = Loading;

  const factory InitialDataModel.error([String? message]) = Error;

  factory InitialDataModel.fromJson(Map<String, dynamic> json) => _$InitialDataModelFromJson(json);
}
Run Code Online (Sandbox Code Playgroud)

文档说明了如何在字段上分配自定义转换器,但不在模型本身上分配

我从后端和 api_provider 中的某个地方获取了 json 我确实
return InitialDataModel.fromJson(json);
无法控制 json 结构,没有“runtimeType”和其他愚蠢的冗余内容

当我想从 json 创建模型时,我打电话给fromJson

flutter: CheckedFromJsonException
Could not create `InitialDataModel`.
There is a problem with "runtimeType".
Invalid union type "null"!
Run Code Online (Sandbox Code Playgroud)

好吧,
我又有了api_provider

final apiProvider = Provider<_ApiProvider>((ref) => _ApiProvider(ref.read));

class _ApiProvider {
  final Reader read;

  _ApiProvider(this.read);

  Future<InitialDataModel> fetchInitialData() async {
    final result = await read(repositoryProvider).send('/initial_data');
    return result.when(
      (json) => InitialDataModel.fromJson(json),
      error: (e) => InitialDataModel.error(e),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

InitialDataModel你可能会看到我正在尝试从 json创建

这行抛出了我上面提到的错误

我不明白如何从 json 创建 InitialDataModel,现在在我的示例中它只是空模型,没有字段

(json) => InitialDataModel.fromJson(json),
json{}这是 Map,即使我传递简单的空地图而不是真正的 json 对象,它也会显示错误

Gio*_*ero 5

最简单的解决方案是使用正确的构造函数而不是_$InitialDataModelFromJson。例子:

@freezed
class InitialDataModel with _$InitialDataModel {
  const factory InitialDataModel() = Data;

  ...

  factory InitialDataModel.fromJson(Map<String, dynamic> json) => Data.fromJson(json);
}
Run Code Online (Sandbox Code Playgroud)

当然,缺点是只有在确定 json 正确时才能使用 fromJson,这不太好。实际上我不会推荐这种方式,因为它给调用者留下了检查有效性和调用正确构造函数的负担。


另一个解决方案(也许是最好的)是遵循文档并创建自定义转换器,即使这需要您拥有两个单独的类。


否则,您可以选择不同的方法并将数据类与联合分开,这样您将拥有一个仅用于请求状态的联合和一个用于成功响应的数据类:

@freezed
class InitialDataModel with _$InitialDataModel {
  factory InitialDataModel(/* here go your attributes */) = Data;

  factory InitialDataModel.fromJson(Map<String, dynamic> json) => _$InitialDataModelFromJson(json);
}

@freezed
class Status with _$Status {
  const factory Status.success(InitialDataModel model) = Data;
  const factory Status.loading() = Loading;
  const factory Status.error([String? message]) = Error;
}

Run Code Online (Sandbox Code Playgroud)

进而

[...]
    return result.when(
      (json) => Status.success(InitialDataModel.fromJson(json)),
      error: (e) => Status.error(e),
    );
[...]

Run Code Online (Sandbox Code Playgroud)