fvi*_*cot 18 enums dart flutter
我需要将我的 Flutter 应用程序中的 Dart 对象存储在 Firestore 中
该对象包括一个枚举属性。
序列化/反序列化此枚举属性的最佳解决方案是什么?
作为字符串
作为一个 Int
我没有找到任何简单的解决方案来做到这一点。
Pau*_*aul 35
简而言之,使用以下枚举序列化的最新实现:
fromJson -> YourEnum.values.byName("property")
toJson -> YourEnum.property。name
toJson/fromJson在你的枚举上只需将这两个函数添加到您的枚举中即可。请注意,您也可以简单地在类中创建这些函数。
enum Manufacturer {
mercedes,
volkswagen,
toyota,
ford;
String toJson() => name;
static Manufacturer fromJson(String json) => values.byName(json);
}
Run Code Online (Sandbox Code Playgroud)
class Car {
final String name;
final Manufacturer manufacturer;
Car(this.name, this.manufacturer);
Map<String, dynamic> toJson() {
return {
"name": name,
"manufacturer": manufacturer.toJson(), // Alternative: manufacturer.name
};
}
static Car fromJson(Map<String, dynamic> jsonData) => Car(
jsonData['name'],
Manufacturer.fromJson(jsonData['manufacturer']), // Alternative: Manufacturer.values.byName(jsonData['manufacturer'])
);
}
Run Code Online (Sandbox Code Playgroud)
Ada*_*dam 34
Flutter 能够生成 JSON 序列化代码。您可以在此处找到教程。它引用了包json_annotation。它还包含对枚举序列化的支持。所以你所需要的就是使用这个工具并用@JsonValue.
从代码文档:
用于指定枚举值如何序列化的注释。
这基本上就是全部。现在让我用代码中的一个小例子来说明。想象一个带有车辆的枚举:
import 'package:json_annotation/json_annotation.dart';
enum Vehicle {
@JsonValue("bike") BIKE,
@JsonValue("motor-bike") MOTOR_BIKE,
@JsonValue("car") CAR,
@JsonValue("truck") TRUCK,
}
Run Code Online (Sandbox Code Playgroud)
然后你可以在你的模型之一中使用这个枚举,例如vehilce_owner.dart看起来像这样:
import 'package:json_annotation/json_annotation.dart';
part 'vehicle_owner.g.dart';
@JsonSerializable()
class VehicleOwner{
final String name;
final Vehicle vehicle;
VehicleOwner(this.name, this.vehicle);
factory VehicleOwner.fromJson(Map<String, dynamic> json) =>
_$VehicleOwnerFromJson(json);
Map<String, dynamic> toJson() => _$VehicleOwnerToJson(this);
}
Run Code Online (Sandbox Code Playgroud)
这是你需要根据json生成howto提供的。现在你需要运行构建器或观察器让 flutter 生成代码:
flutter pub run build_runner build
Run Code Online (Sandbox Code Playgroud)
然后生成的代码将如下所示。看一下根据_$VehicleEnumMap您的@JsonValue注释生成的:
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'vehicle_owner.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
// more generated code omitted here ....
const _$VehicleEnumMap = {
Vehicle.BIKE: 'bike',
Vehicle.MOTOR_BIKE: 'motor-bike',
Vehicle.CAR: 'car',
Vehicle.TRUCK: 'truck',
};
Run Code Online (Sandbox Code Playgroud)
Rya*_*ell 13
如果有点不完整,Gunter 的回答是正确的。
JSON serializable 确实处理了 Enum 与字符串之间的相互转换,以下是生成内容的一些示例代码:
const _$HoursEnumMap = <Hours, dynamic>{
Hours.FullTime: 'FullTime',
Hours.PartTime: 'PartTime',
Hours.Casual: 'Casual',
Hours.Contract: 'Contract',
Hours.Other: 'Other'
};
Run Code Online (Sandbox Code Playgroud)
作为回报,它使用这个相当钝的函数将其转换回来:
T _$enumDecode<T>(Map<T, dynamic> enumValues, dynamic source) {
if (source == null) {
throw ArgumentError('A value must be provided. Supported values: '
'${enumValues.values.join(', ')}');
}
return enumValues.entries
.singleWhere((e) => e.value == source,
orElse: () => throw ArgumentError(
'`$source` is not one of the supported values: '
'${enumValues.values.join(', ')}'))
.key;
}
Run Code Online (Sandbox Code Playgroud)
我厌倦了这个我决定做一个小包来消除复杂性,它对我来说非常方便:
https://pub.dev/packages/enum_to_string
至少它的单元通过复制/粘贴解决方案进行了测试。欢迎任何添加或请求请求。
我这样做的方法是只保存枚举的索引。
假设您有一个枚举:
enum Location {
EARTH,
MOON,
MARS,
}
Run Code Online (Sandbox Code Playgroud)
以及一个使用以下方法保存枚举的类:
/// 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'],
),
);
}
Run Code Online (Sandbox Code Playgroud)
最好的方法是使用 enums 整数值,因为它是最容易从 int/enum 类型转换到 int/enum 类型的。
您需要注意的是,仅在修改枚举时才在末尾添加新的枚举值,否则持久化的值将变得无效。
https://pub.dartlang.org/packages/built_value提供类的代码生成,并拥有自己的枚举,并为您进行 JSON(反)序列化。
https://pub.dartlang.org/packages/json_serialized似乎直接支持 Dart 枚举,但我自己没有使用过。