gpt4 book ai didi

flutter - json_serializable - 将通用字段添加到卡住/json_serializable 类

转载 作者:行者123 更新时间:2023-12-04 14:56:35 28 4
gpt4 key购买 nike

我如何制作 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);
}
我试过使用 @With.fromString('AdministrativeArea<House>')来自文档,但无法将其正确应用于此类。
错误之一:

lib/src/common/enums/tags/common/vegan_item_tag.freezed.dart:142:32:Error: Too few positional arguments: 2 required, 1 given.
$$_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(
Map<String, Object?> json,
T Function(Object?) fromJsonT,
) => VeganItemTag(
iconCodePoint: json['iconCodePoint'] as int,
id: fromJsonT(json['id']),
name: json['name'] as String,
);
}

最佳答案

这个问题有几种解决方案。但是在所有这些中,您都需要将您的类显式转换为 Firebase 可以处理的泛型类型,例如 StringMap<dynamic, String> .
实现这种行为的 3 种方法是:
从Json到Json
这比 JsonConverters 维护起来更麻烦在复杂的场景中,所以我会为您的解决方案放弃这个选项。
Json转换器
它适用于通过继承自动转换特定类或抽象类,但从具有不同数据的泛型类型来存储它可能不是您所需要的。如果您总是从泛型类型 T 中保存相同的值您可以尝试通过实现的抽象类来使用此解决方案。
通用参数工厂
这才是你真正要问的。与 genericArgumentFactories 合作在 json_serializableFreezed不容易,我在 Freezed package 上发现了一个错误同时。
但是我设法让这段代码工作,这是实际的解决方案🧭。

@freezed
@JsonSerializable(genericArgumentFactories: true)
class VeganItemTagV2<T> with _$VeganItemTagV2<T> {
const VeganItemTagV2._();

const factory VeganItemTagV2({
required int iconCodePoint,
required T id,
required String name,
}) = _VeganItemTag<T>;

//It only works with block bodies and not with expression bodies
//I don't know why
factory VeganItemTagV2.fromJson(
Map<String, dynamic> json, T Function(Object? json) fromJsonT) {
return _$VeganItemTagV2FromJson<T>(json, fromJsonT);
}

Map<String, dynamic> toJson(Object Function(T value) toJsonT) {
return _$VeganItemTagV2ToJson<T>(this, toJsonT);
}
}
这会在 toJson 上添加转换器和 fromJson根据泛型类型使用的方法。
笔记。这些方法不能作为某些错误的表达式,因为它不能编译但可以与块体一起使用。 Freezed does not oficcially support it所以你可以考虑在没有 Freezed 包的情况下创建这个类。
这是一个带有 String 封装类的示例和一个测试类来看看它是如何工作的:
class VeganId {
final String id;

VeganId(this.id);

String itemId() {
return id;
}

@override
String toString() {
return 'VeganId{id: $id}';
}

@override
bool operator ==(Object other) =>
identical(this, other) ||
other is VeganId && runtimeType == other.runtimeType && id == other.id;

@override
int get hashCode => id.hashCode;
}
以及运行良好的测试
  test('veganItemV2 from and toJson', () {
final dto = VeganItemTagV2<VeganId>(
iconCodePoint: 1,
id: VeganId("veganID"),
name: "name",
);

final Map<String, dynamic> actualToJson = dto.toJson((id) => id.itemId());

expect(actualToJson, {"iconCodePoint": 1, "id": "veganID", "name": "name"});

final VeganItemTagV2 actualFromJson = VeganItemTagV2<VeganId>.fromJson(
actualToJson,
(json) =>
VeganId(json as String),
);

expect(actualFromJson, dto);
});

关于flutter - json_serializable - 将通用字段添加到卡住/json_serializable 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67856555/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com