冻结如何在顶级模型上分配我自己的 JsonConverter?
freezed how to assign my own JsonConverter on top level model?
我已冻结模型(简体):
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);
}
文档说明了如何在字段而不是模型本身上分配自定义转换器
我从后端和 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"!
好的,再来一次
我有 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),
);
}
}
您可能会看到我正在尝试从 json
创建 InitialDataModel
这一行抛出了我上面提到的错误
我不明白如何从 json 创建 InitialDataModel,现在在我的示例中它只是空模型,没有字段
(json) => InitialDataModel.fromJson(json),
json
这是地图,即使我传递简单的空地图 {}
而不是真正的 json 对象
,它也会显示错误
最简单的解决方案是使用正确的构造函数而不是 _$InitialDataModelFromJson。示例:
@freezed
class InitialDataModel with _$InitialDataModel {
const factory InitialDataModel() = Data;
...
factory InitialDataModel.fromJson(Map<String, dynamic> json) => Data.fromJson(json);
}
缺点当然是只有当您确定自己拥有正确的 json 时才能使用 fromJson,这不是很好。我实际上不推荐这种方式,因为它留给了调用者检查有效性和调用正确构造函数的负担。
另一个可能是最好的解决方案是遵循 documentation 并创建一个自定义转换器,即使这需要您有两个单独的 classes。
否则,您可以选择不同的方法,将数据 class 从联合中分离出来,这样您将拥有一个仅用于请求状态的联合,以及一个用于请求状态的数据 class成功响应:
@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;
}
然后
[...]
return result.when(
(json) => Status.success(InitialDataModel.fromJson(json)),
error: (e) => Status.error(e),
);
[...]
我已冻结模型(简体):
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);
}
文档说明了如何在字段而不是模型本身上分配自定义转换器
我从后端和 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"!
好的,再来一次
我有 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),
);
}
}
您可能会看到我正在尝试从 json
创建InitialDataModel
这一行抛出了我上面提到的错误
我不明白如何从 json 创建 InitialDataModel,现在在我的示例中它只是空模型,没有字段
(json) => InitialDataModel.fromJson(json),
json
这是地图,即使我传递简单的空地图 {}
而不是真正的 json 对象
最简单的解决方案是使用正确的构造函数而不是 _$InitialDataModelFromJson。示例:
@freezed
class InitialDataModel with _$InitialDataModel {
const factory InitialDataModel() = Data;
...
factory InitialDataModel.fromJson(Map<String, dynamic> json) => Data.fromJson(json);
}
缺点当然是只有当您确定自己拥有正确的 json 时才能使用 fromJson,这不是很好。我实际上不推荐这种方式,因为它留给了调用者检查有效性和调用正确构造函数的负担。
另一个可能是最好的解决方案是遵循 documentation 并创建一个自定义转换器,即使这需要您有两个单独的 classes。
否则,您可以选择不同的方法,将数据 class 从联合中分离出来,这样您将拥有一个仅用于请求状态的联合,以及一个用于请求状态的数据 class成功响应:
@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;
}
然后
[...]
return result.when(
(json) => Status.success(InitialDataModel.fromJson(json)),
error: (e) => Status.error(e),
);
[...]