我试图通过这个YouTube 教程遵循 Clean Architecture ,因此我在数据层中有一组模型对象来扩展实体对象。
由于我有很多模型,其中一些模型有很多字段,我希望使用json_serializable包来自动生成样板代码,这些代码是工厂以及与 Json 和 fromJson 转换器方法相关的样板代码。
但是运行时:
flutter pub run build_runner 构建
它失败:
[严重]由于类型原因,无法生成
fromJson代码。serversServer
我的数据架构如下,在数据层:
- HostModel extends Host(Entity)
- String name,
- List<ServerModel> servers,
- ServerModel extends Server(Entity)
- ... // many many fields
Run Code Online (Sandbox Code Playgroud)
然而,当且仅当所有实体类都用 注释时,@JsonSerializable(explicitToJson: true)我才设法使其工作。
这对我来说非常困扰,因为我了解到清洁架构通过层分离所有关注点并遵循 SOLID 原则。所以我认为实体不应该“意识到”原始模型。并且反序列化方法应该可以用任何其他方法(例如 XML)替代,这显然违反了这里的原则。
我该如何解决这个问题?谢谢您的帮助!
我正在尝试为冻结包生成的联合实现 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);
}
Run Code Online (Sandbox Code Playgroud)
我想要/fromJson 的行为如下:
Result error = Result.error('some error');
expect(error.toJson(), {'type': 'error', 'message': 'some error'});
expect(Result.fromJson({'type': 'error', 'message': 'some error'}), error);
Run Code Online (Sandbox Code Playgroud)
文档中说明您可以使用 a 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;
} …Run Code Online (Sandbox Code Playgroud) 我必须序列化 json 才能从 Enum 创建特定的子类,该子类是包含抽象类目标的一个类的属性
class Test {
Outcome outcome;
TestType type;
}
abstract class Outcome {
String attribute;
}
class PackageOutcome extends Outcome {
String packageAttribute;
}
class FlexibilityOutcome extends Outcome {
String flexibilityAttribute;
}
Run Code Online (Sandbox Code Playgroud)
Outcome 没有序列化 json 的工厂方法,但 PackageOutcome 和 FlexibilityOutcome 有。
在工厂方法中,Test.toJson()如果我有特定类型的 Enum TestType,我会创建 PackageOutcome,如果我有另一种类型,我会创建FlexibilityOutcome为测试结果。
你可以用 json_serialized 来做到这一点吗?有一些教程解释了如何做到这一点?
Dart 的json_serialized插件,在自动生成一些容易出错且繁琐的代码部分方面做得很好,以换取一些样板文件:两个方法、一个注释和一个对生成文件的引用。
import 'package:json_annotation/json_annotation.dart';
part 'location.g.dart';
@JsonSerializable()
class Location {
final double lat;
final double lng;
Location(this.lat, this.lng);
factory Location.fromJson(Map<String, dynamic> json) =>
_$LocationFromJson(json);
Map<String, dynamic> toJson() => _$LocationToJson(this);
}
Run Code Online (Sandbox Code Playgroud)
显然,这也最好由机器完成,就像此类的构造函数一样:我只需编写最终字段,然后按 alt+enter 键,Android Studio 就会为我放置构造函数。
有人知道如何让 Android Studio 为 json_serialized 做到这一点吗?
如何使Freezed对象采用泛型类型?我想做这个:
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:vepo/src/entity_types/option_entity.dart';
part 'vegan_item_tag.freezed.dart';
part 'vegan_item_tag.g.dart';
@freezed
abstract class VeganItemTag<T>
with _$VeganItemTag<T>
implements OptionEntity<T> {
const factory VeganItemTag({int? iconCodePoint, T? id, String? name}) =
_VeganItemTag;
const VeganItemTag._();
factory VeganItemTag.fromJson(Map<String, dynamic> json) =>
_$VeganItemTagFromJson(json);
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用@With.fromString('AdministrativeArea<House>')文档中的内容,但无法将其正确应用到此类。
错误之一:
lib/src/common/enums/tags/common/vegan_item_tag.freezed.dart:142:32:错误:位置参数太少:需要 2 个,给定 1 个。
$ $_VeganItemTagFromJson(json);
我想我可能是在正确的轨道上,但它不再生成文件vegan_item_tag.g.dart:
@freezed
abstract class VeganItemTag<T>
with _$VeganItemTag<T>
implements OptionEntity<T> {
const factory VeganItemTag(
{required int iconCodePoint,
required T id,
required String name}) = _VeganItemTag;
const VeganItemTag._();
factory VeganItemTag.fromJson( …Run Code Online (Sandbox Code Playgroud) 我们正在尝试创建一个通用的 Category 类。目前,我们不确定类别是否以整数或 UUID 作为键。因此,我们现在需要 id 是通用的。一切正常。但是,我们无法使用该freezed包生成 fromJson() 和 toJson()。
import \'package:freezed_annotation/freezed_annotation.dart\';\n\npart \'category.freezed.dart\';\npart \'category.g.dart\';\n\n@freezed\n@JsonSerializable(genericArgumentFactories: true)\nclass Category<T> with _$Category<T> {\n factory Category({\n required T id,\n required String name,\n required String imageUrl,\n }) = _Category;\n\n factory Category.fromJson(Map<String, dynamic> json) =>\n _$CategoryFromJson(json);\n}\nRun Code Online (Sandbox Code Playgroud)\n错误:
\nCould not generate `fromJson` code for `id` because of type `T` (type parameter).\nTo support type parameters (generic types) you can:\n* Use `JsonConverter`\n https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html\n* Use `JsonKey` fields `fromJson` and `toJson`\n https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html\n https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html\n* Set `JsonSerializable.genericArgumentFactories` to `true`\n …Run Code Online (Sandbox Code Playgroud) 我有一个类,我试图将其与 Freezed、Json Serialized 和 Hive 一起使用。运行dart run build_runner build并生成必要的类后,我的编译器给出以下错误:
: Error: Can't use '_$FooBarFromJson' because it is declared more than once.
和
: Error: '_$FooBarFromJson' is already declared in this scope.
part 'foobar.freezed.dart';
part 'foobar.g.dart';
@freezed
@JsonSerializable(explicitToJson: true)
@HiveType(typeId: 0)
class FooBar extends HiveObject with _$FooBar {
factory FooBar({
@HiveField(0) required int baz
}) = _FooBar;
factory FooBar.fromJson(Map<String, dynamic> json) =>
_$FooBarFromJson(json);
}
}
Run Code Online (Sandbox Code Playgroud)
查看生成的类后,我的foobar.g.dart文件包含以下方法:
FooBar _$FooBarFromJson(Map<String, dynamic> json) => FooBar(
baz: json['baz'] as int,
); …Run Code Online (Sandbox Code Playgroud) 我使用冻结的包来处理不可变模型,并利用json_serialized包的内置功能进行 json 序列化。我有一个简单的User类/模型,具有不同的联合类型(UserLoggedIn、UserGeneral、UserError):
@freezed
class User with _$User {
const factory User(String id, String email, String displayName) =
UserLoggedIn;
const factory User.general(String email, String displayName) = UserGeneral;
const factory User.error(String message) = UserError;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}
Run Code Online (Sandbox Code Playgroud)
由于我使用多个构造函数并且不希望我的 API 包含runtimeType文档建议的密钥,因此我可以编写一个转换器(向下滚动一点,句子开头为:如果您不控制 JSON 响应,然后您可以实现自定义转换器。)。
因此,基于此,我编写了以下转换器类:
class UserConverter implements JsonConverter<User, Map<String, dynamic>> {
const UserConverter();
@override
User fromJson(Map<String, dynamic> json) {
if (json['id'] …Run Code Online (Sandbox Code Playgroud) 我尝试创建一个这样的轮廓模型;fromJson看起来不错,但我有一个问题toJson:
@Freezed(
fromJson: true,
toJson: true,
map: FreezedMapOptions.none,
when: FreezedWhenOptions.none,
)
class ProfileAttribute with _$ProfileAttribute {
const factory ProfileAttribute({
@JsonKey(name: '_id', includeIfNull: false) final String? id,
final String? uid,
final String? username,
final String? name,
final String? phone,
final String? email,
final String? address,
final String? image,
}) = _ProfileAttribute;
factory ProfileAttribute.fromJson(Map<String, dynamic> json) =>
_$ProfileAttributeFromJson(json);
}
Run Code Online (Sandbox Code Playgroud)
我看到调试 toJson 将发送:
"attributes": {
"_id": null,
"uid": null,
"username": null,
"name": null,
"phone": null,
"email": "asdasda@gmasd.com",
"address": null, …Run Code Online (Sandbox Code Playgroud) flutter flutter-dependencies json-serializable flutter-freezed
发布这个问题是为了我自己回答。希望这对某人有帮助。
问题:使用 flutter 生成代码freezed,但将 json 字段名称更改为特定的重命名模式。