1

我的主要问题是我想防止在通过解析 json 创建对象时字段值变为 null。该字段是 Map<String, enum>。

示例代码:

import 'package:json_annotation/json_annotation.dart';

enum Letter{ A, B,C}
@JsonSerializable()
class example{
    @JsonKey(defaultValue: {
        'C': Letter.C
    })
    Map<String, Letter> letters = {
        'A': Letter.A,
        'B':Letter.B
    };
}

运行时出现错误:

flutter pub run build_runner build

错误信息是:

错误运行 JsonSerializableGenerator 错误与@JsonKeyon lettersdefaultValueMap > Letter,它必须是文字。

发现这个: https ://github.com/google/json_serializable.dart/issues/361

但是,如果我尝试使用转换器方法,我会遇到其他问题,因此尝试解决根本问题。

4

2 回答 2

0

使用枚举的 name 属性和 byName 方法

import 'dart:convert';

void main() {
  Person raj = Person(name: 'Raj', favIcecream: Icecream.pista);
  print(raj.toJson());

  Person rajV2 = Person.fromJson(raj.toJson());
  print(rajV2.toJson());

  final isBothInstanceEqual = raj == rajV2;
  print('> Both instancecs are equal is $isBothInstanceEqual');
}

enum Icecream {
  vanilla,
  pista,
  strawberry,
}

class Person {
  String name;
  Icecream favIcecream;
  Person({
    required this.name,
    required this.favIcecream,
  });

  Map<String, dynamic> toMap() {
    return {
      'name': name,
      'favIcecream': favIcecream.name, // <- this is how you should save
    };
  }

  factory Person.fromMap(Map<String, dynamic> map) {
    return Person(
      name: map['name'] ?? '',
      favIcecream: Icecream.values.byName(map['favIcecream']), // <- back to enum
    );
  }

  String toJson() => json.encode(toMap());

  factory Person.fromJson(String source) => Person.fromMap(json.decode(source));

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is Person &&
        other.name == name &&
        other.favIcecream == favIcecream;
  }

  @override
  int get hashCode => name.hashCode ^ favIcecream.hashCode;
}
于 2022-02-24T15:00:46.793 回答
-1

一种适用于最小规模的解决方案。

pupspec.yaml:

name: playground
description: A simple command-line application.

environment:
  sdk: '>=2.8.1 <3.0.0'
dependencies:
  json_annotation: ^3.0.1

dev_dependencies:
  build_runner: ^1.10.0
  json_serializable: ^3.3.0
  pedantic: ^1.9.0

操场飞镖:

import 'package:json_annotation/json_annotation.dart';
part 'playground.g.dart';
enum Letter{   A,  B,  C}
@JsonSerializable()
class example{
    example(){}
    @JsonKey(fromJson: parseMap, toJson: toStringMap)
    Map<String, Letter> letters = {
        'A': Letter.A,
        'B':Letter.B
    };

    factory example.fromJson(Map<String, dynamic> json) => _$exampleFromJson(json);
    Map<String, dynamic> toJson() => _$exampleToJson(this);

    static Map<String, Letter> parseMap(Map<String,String> m){
      if(m==null){
        return {
          'C': Letter.C
        };
      }
      Map<String, Letter> result ={};
      for(String key in m.keys){
         result[key]=Letter.values.firstWhere((e) => e.toString() == m[key]); 
      }
      return result;
    }
    static Map<String, String> toStringMap(Map<String,Letter> m){
      if(m==null){
        return {
          'C': 'C'
        };
      }
      Map<String, String> result ={};
      for(String key in m.keys){
         result[key]=m[key].toString(); 
      }
      return result;
    }
}

void main(List<String> arguments) {
  var ex = example.fromJson({});
  print(ex.letters.values);
  var ex2 = new example();
  var m =ex2.toJson();
  print(m);
  var ex3 = new example();
  ex3.letters=null;
  var m2 =ex3.toJson();
  print(m2);
}

跑:

pub run build_runner build
dart .\bin\playground.dart

输出:

(字母.C)
{字母:{A:字母.A,B:字母.B}}
{字母:{C:C}}

于 2020-06-25T11:16:47.447 回答