【问题标题】:Dart json_serializable defaultValue for Map with Enum Value具有枚举值的映射的 Dart json_serializable defaultValue
【发布时间】:2020-10-15 05:56:39
【问题描述】:

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

示例代码:

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 错误,@JsonKey on lettersdefaultValueMap &gt; Letter,必须是字面量。

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

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

【问题讨论】:

    标签: dart json-serializable


    【解决方案1】:

    使用枚举的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;
    }
    

    【讨论】:

      【解决方案2】:

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

      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
      

      playground.dart:

      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:Letter.A,B:Letter.B}}
      {字母:{C:C}}

      【讨论】:

        猜你喜欢
        • 2019-08-23
        • 2019-07-20
        • 1970-01-01
        • 2015-06-27
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 2016-12-13
        • 2017-10-21
        相关资源
        最近更新 更多