Enums 如何使用Dart/FLIFT将枚举属性序列化/反序列化到Firestore?

Enums 如何使用Dart/FLIFT将枚举属性序列化/反序列化到Firestore?,enums,dart,flutter,Enums,Dart,Flutter,我需要在Firestore中存储颤振应用程序中的Dart对象 此对象包含枚举属性 序列化/反序列化此枚举属性的最佳解决方案是什么 一串 作为Int 我找不到任何简单的解决方案。最好的方法是使用枚举整数值,因为它最容易从/转换为int/enum类型 您需要注意,只有在修改枚举时才在末尾添加新的枚举值,否则持久化的值将变得无效 为类提供代码生成,有自己的枚举,并为您执行JSON(反)序列化 似乎直接支持Dart枚举,但我自己没有使用过。如果有点不完整,Gunter的答案是正确的 JSON ser

我需要在Firestore中存储颤振应用程序中的Dart对象

此对象包含枚举属性

序列化/反序列化此枚举属性的最佳解决方案是什么

  • 一串

  • 作为Int


我找不到任何简单的解决方案。

最好的方法是使用枚举整数值,因为它最容易从/转换为int/enum类型

您需要注意,只有在修改枚举时才在末尾添加新的枚举值,否则持久化的值将变得无效

为类提供代码生成,有自己的枚举,并为您执行JSON(反)序列化


似乎直接支持Dart枚举,但我自己没有使用过。

如果有点不完整,Gunter的答案是正确的

JSON serializable处理枚举与字符串之间的转换,以下是生成内容的示例代码:

const_$HoursEnumMap={
Hours.FullTime:“FullTime”,
小时。兼职:“兼职”,
小时。休闲:“休闲”,
小时数。合同:'合同',
小时。其他:“其他”
};
作为回报,它用这个相当迟钝的函数将其转换回来:

T_$enumDecode(映射枚举值,动态源){
if(source==null){
throw ArgumentError('必须提供一个值。支持的值:'
“${enumValues.values.join(',')}”);
}
返回enumValues.entries
.singleWhere((e)=>e.value==source,
orElse:()=>抛出参数错误(
“`$source`不是受支持的值之一:”
'${enumValues.values.join(',')}'))
钥匙
}
我对此感到非常厌倦,我决定制作一个小程序包来消除复杂性,它对我来说非常方便:


至少它的单元在复制/粘贴解决方案上进行了测试。欢迎任何添加或拉取请求。

flatter能够生成JSON序列化代码。您可以找到的教程。它引用了包。它还包含对枚举序列化的支持。因此,您所需要的就是使用此工具并使用
@JsonValue
注释您的枚举值

从:

用于指定枚举值序列化方式的批注

基本上就这些。现在让我用一个小的代码示例来说明。设想一个包含车辆的枚举:

import'package:json_annotation/json_annotation.dart';
枚举车辆{
@JsonValue(“自行车”)自行车,
@JsonValue(“摩托车”)摩托车,
@JsonValue(“汽车”)汽车,
@JsonValue(“卡车”)卡车,
}
然后,您可以在一个模型中使用此枚举,例如
vehilce\u owner.dart
,如下所示:

import'package:json_annotation/json_annotation.dart';
“车辆所有人g.dart”部分;
@JsonSerializable()
类别车主{
最后的字符串名;
最终车辆;
车主(此名称,此车辆);
factory VehicleOwner.fromJson(映射json)=>
_$VehicleOwnerFromJson(json);
映射到JSON()=>$VehicleOwnerToJson(此);
}
这是您需要根据提供的。现在,您需要运行构建器或让Flatter生成代码:

flatter pub run build\u runner build
然后生成的代码如下所示。请查看根据您的
@JsonValue
注释生成的
.$VehicleEnumMap

//生成的代码-不要手动修改
“车主.飞镖”的一部分;
// **************************************************************************
//JsonSerializableGenerator
// **************************************************************************
//这里省略了更多生成的代码。。。。
常数$VehicleEnumMap={
Vehicle.BIKE:“BIKE”,
车辆.摩托车:“摩托车”,
Vehicle.CAR:“CAR”,
Vehicle.TRUCK:“TRUCK”,
};

我的方法是只保存枚举的索引

假设您有一个枚举:

enum Location {
  EARTH,
  MOON,
  MARS,
}
以及使用以下方法保存枚举的类:

/// Returns a JSON like Map of this User object
  Map<String, dynamic> toJSON() {
    return {
      "name": this.name,
      "location": this.location.index,
    };
  }

  /// Returns [Player] build from a map with informationen
  factory Player.fromJson(Map<String, dynamic> parsedJson) {
    return new Player(
      name: parsedJson['name'],
      location: Location.values.elementAt(
        parsedJson['location'],
      ),
    );
  }
///返回此用户对象的类似JSON的映射
映射到JSON(){
返回{
“名字”:这个名字,
“位置”:this.location.index,
};
}
///使用informationen从地图返回[Player]构建
factory Player.fromJson(Map parsedJson){
返回新玩家(
名称:parsedJson['name'],
位置:location.values.elementAt(
parsedJson['location'],
),
);
}

Checkout
Vnum
如果您使用此处所述的json生成器,那么当遇到带有@JsonValue的枚举值时,$enumDecode是自动生成的方法。如果您可以使用json_serializable和enum_to_字符串,像Java中的objectMapper.setPropertyNamegstrategy()Hey@Adam一样,创建一个用例,那么真正酷的是什么呢。实际上,我现在正在尝试扩展json serializable,以生成一个“填充”函数,从而深入了解它。这不是一个完美的解决方案,但您可以使用@JsonKey(toJson:(value)=>…)注释字段,类似于fromJson。这将允许您手动处理转换,如果您需要,可以使用不同的值。非常感谢您在dart中堵塞了这个讨厌的漏洞。最受欢迎的答案是code-gen,这真的很让人难过。“最好的方法是使用枚举整数值”,然后是“你需要注意,你只在末尾添加新的枚举值[…],否则持久值将无效”,这与我的观点相矛盾。我发现Dart中的枚举也非常有限。有了新的扩展方法,手动创建从/到转换器变得更加方便。@Philippe Fanaro感谢您的编辑建议,但我认为您最好将其添加为注释。@GünterZöchbauer,这种编辑,据说会增加价值的编辑(如果我的错误,请说!),应该在答案中,而不是在评论中。评论部分应该只是一个讨论