zoukankan      html  css  js  c++  java
  • Dart 处理json,built_value库

    原文链接
    文档

    import 'dart:convert';
    
    main() async {
      // json 转化为 map
      String jsonStr = '''
        [
          {"name": "ajanuw"},
          {"name": "suou"}
        ]
      ''';
    
      var jsonObj = jsonDecode(jsonStr);
      print(jsonObj[0]['name'] == 'ajanuw'); // true
    
      // list<Map> 转化为 json字符串
      var scores = [
        {'score': 40},
        {'score': 80},
        {'score': 100, 'overtime': true, 'special_guest': null}
      ];
      var jsonText = jsonEncode(scores);
      print(jsonText);
    }
    

    使用对象添加模板 JSON to Dart

    import 'dart:convert';
    
    class MyInfo {
      MyInfo({this.age, this.name});
    
      String name;
      int age;
    
      factory MyInfo.fromJson(Map<String, dynamic> jsonMap) {
        return MyInfo(
          name: jsonMap['name'],
          age: jsonMap['age'],
        );
      }
    }
    
    main(List<String> args) {
      String jsonStr = '''
        {
          "name": "ajanuw",
          "age": 12
        }
      ''';
      var parsed = jsonDecode(jsonStr);
      MyInfo data = MyInfo.fromJson(parsed);
      print(data.age);
    }
    

    使用“built_value”库来处理json

    我在这里使用"stagehand console-full"创建的项目示例,项目名叫"dart_test"

    1) 安装依赖

    dependencies:
      ...
      built_value:
      built_collection:
    
    dev_dependencies:
      ...
      build_runner:
      built_value_generator:
    
    1. 准备json数据
    {
          "id": 157538,
          "date": "2017-07-21T10:30:34",
          "date_gmt": "2017-07-21T17:30:34",
          "type": "post",
          "link": "https://example.com",
          "title": {
              "rendered": "Json 2 dart built_value converter"
          },
          "tags": [
              1798,
              6298
          ]
    }
    
    1. 创建文件"lib/models/hello.dart",文件名很重要必须要要和你的class名一样
    import 'dart:convert';
    
    import 'package:built_collection/built_collection.dart';
    import 'package:built_value/built_value.dart';
    import 'package:built_value/serializer.dart';
    
    part 'hello.g.dart';
    
    abstract class Hello implements Built<Hello, HelloBuilder> {
      Hello._();
    
      factory Hello([updates(HelloBuilder b)]) = _$Hello;
    
      @BuiltValueField(wireName: 'id')
      int get id;
      @BuiltValueField(wireName: 'date')
      String get date;
      @BuiltValueField(wireName: 'date_gmt')
      String get dateGmt;
      @BuiltValueField(wireName: 'type')
      String get type;
      @BuiltValueField(wireName: 'link')
      String get link;
      @BuiltValueField(wireName: 'title')
      Title get title;
    
      @nullable // 可为空,返回null
      @BuiltValueField(wireName: 'tags')
      BuiltList<int> get tags;
    
      String toJson() {
        return jsonEncode(serializers.serializeWith(Hello.serializer, this));
      }
    
      static Hello fromJson(String jsonString) {
        return serializers.deserializeWith(
            Hello.serializer, jsonDecode(jsonString));
      }
    
      static Serializer<Hello> get serializer => _$helloSerializer;
    }
    
    abstract class Title implements Built<Title, TitleBuilder> {
      Title._();
    
      factory Title([updates(TitleBuilder b)]) = _$Title;
    
      @BuiltValueField(wireName: 'rendered')
      String get rendered;
    
      String toJson() {
        return jsonEncode(serializers.serializeWith(Title.serializer, this));
      }
    
      static Title fromJson(String jsonString) {
        return serializers.deserializeWith(
            Title.serializer, jsonDecode(jsonString));
      }
    
      static Serializer<Title> get serializer => _$titleSerializer;
    }
    
    1. 保存文件后,在项目根目录下运行命令, 生成"lib/models/hello.g.dart"文件
    flutter packages pub run build_runner build   // 执行一次build命令
    flutter packages pub run build_runner watch  // 文件更改自动build
    flutter packages pub run build_runner watch --delete-conflicting-outputs  // 删除旧文件在build
    
    1. 创建"lib/models/serializers.dart"文件,编写下面的代码后,保存会生成"lib/models/serializers.g.dart"文件
    import 'package:built_collection/built_collection.dart';
    import 'package:built_value/serializer.dart';
    import 'package:built_value/standard_json_plugin.dart';
    import 'package:dart_test/models/hello.dart';
    
    part 'serializers.g.dart';
    
    @SerializersFor(const [
      Hello
    ])
    final Serializers serializers = (_$serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();
    
    1. 编写“bin/main.dart"
    import 'package:dart_test/models/hello.dart';
    
    String jsonStr = '''
     {
          "id": 157538,
          "date": "2017-07-21T10:30:34",
          "date_gmt": "2017-07-21T17:30:34",
          "type": "post",
          "link": "https://example.com",
          "title": {
              "rendered": "Json 2 dart built_value converter"
          },
          "tags": [
              1798,
              6298
          ]
        }
    ''';
    
    main(List<String> args) {
      Hello hello = Hello.fromJson(jsonStr);
      print(hello.title.rendered);
      print(hello.tags.length);
    }
    
    1. 保存文件后执行
    > dart bin/main.dart
    Json 2 dart built_value converter
    2
    

    在vscode中隐藏 “*.g.dart”生成的文件

      "files.exclude": {
        "**/*.g.dart": true
      }
    

    built_value处理json不要有这样的数据 { key: [[{}], [{}],...] } 转换为这样: { key: [{key: []}, {key: []},...] }

    创建枚举

      int get age;
      TypeStatus get type => age < 10 ? TypeStatus.a : TypeStatus.b;
    
    enum TypeStatus {
      a,
      b,
    }
     // or
    class TypeStatus extends EnumClass {
      static const TypeStatus a = _$a;
      static const TypeStatus b = _$b;
      const TypeStatus._(String name) : super(name);
      static BuiltSet<TypeStatus> get values => _$values;
      static TypeStatus valueOf(String name) => _$valueOf(name);
    }
    

    手动创建dto模型

    import 'dto/hello_dto/hello_dto.dart';
    
    String jsonStr = '''
     {
          "id": 157538,
          "date": "2017-07-21T10:30:34",
          "date_gmt": "2017-07-21T17:30:34",
          "type": "post",
          "link": "https://example.com",
          "title": {
              "rendered": "Json 2 dart built_value converter"
          },
          "tags": [
              1798,
              6298
          ]
        }
    ''';
    
    main(List<String> args) {
      var r = HelloDto(
        (b) => b
          ..id = 1
          ..date = 'date'
          ..dateGmt = 'dateGmt'
          ..type = 'get'
          ..link = 'link'
          ..title.rendered = 'title'
          ..tags.addAll([1, 2]),
      );
    
      print(r);
    }
    
    λ dart test.dart
    HelloDto {
      id=1.0,
      date=date,
      dateGmt=dateGmt,
      type=get,
      link=link,
      title=TitleDto {
        rendered=title,
      },
      tags=[1, 2],
      arrobj=[],
    }
    

    rebuild重建实例

      var hello = HelloDto.fromJson(jsonStr);
      var hello2 = hello.rebuild((b) => b.type = 'get');
      print(hello == hello2); // false
       
      // 数据一样是相等的
      var hello = HelloDto.fromJson(jsonStr);
      var hello2 = HelloDto.fromJson(jsonStr);
      print(hello == hello2); // true
    

    在flutter中更新数据

    import 'package:flutter/material.dart';
    import 'package:flutter_demo/dto/hello_dto/hello_dto.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: HomePage(),
        );
      }
    }
    
    class HomePage extends StatefulWidget {
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      List<HelloDto> data;
    
      @override
      void initState() {
        super.initState();
    
        data = HelloDto.fromListJson('''[{"a":"a1","b":"b1"},{"a":"a2","b":"b2"}]''');
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Home Page'),
          ),
          body: ListView(
            children: <Widget>[
              for (var it in data)
                ListTile(
                  title: Text(it.a),
                  subtitle: Text(it.b),
                ),
            ],
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              setState(() {
                data[0] = data[0].rebuild((b) => b.a = 'new title');
              });
            },
            child: Icon(Icons.hot_tub),
          ),
        );
      }
    }
    

    为可能为null的数据设置默认值

      @nullable
      @BuiltValueField()
      int get id;
    
      static HelloDto fromJson(String jsonString) {
        return serializers
            .deserializeWith(HelloDto.serializer, jsonDecode(jsonString))
            .rebuild(
               // 在这里设置
              (b) => b..id ??= 0,
            );
      }
    
      var hello = HelloDto.fromJson('{"id": null}');
      print(hello);
      print(hello.id); //=> 0
    
  • 相关阅读:
    连载《一个程序猿的生命周期》-《发展篇》- 34.如果自己有想法去“创业”,怎么平衡与工作之间的关系
    连载《一个程序猿的生命周期》-《发展篇》- 33.是不是又走在“创业”的路上?!
    连载《一个程序猿的生命周期》-《发展篇》- 32.疫情中复工,跌宕起伏的2019,发展元年的2020
    连载《一个程序猿的生命周期》-《发展篇》- 28.恰逢五四,我们又走在奋斗的路上吗?
    连载《一个程序猿的生命周期》-《发展篇》- 27.从来没有996过,仍然需要人生的选择权
    连载《一个程序猿的生命周期》-《发展篇》- 26.且听风吟,静待花开,慢慢走向人生赢家
    连载《一个程序猿的生命周期》-《发展篇》- 25.论一个非正式项目经理的自我修养
    连载《一个程序猿的生命周期》-《发展篇》- 24.你所掌握的技术,创造的价值会越来越低
    连载《一个程序猿的生命周期》-《发展篇》- 23.两年多的时间,从孤家寡人到10多人的团体,经历了什么
    6年前端开发被实习生替代,所谓“经验”一文不值!
  • 原文地址:https://www.cnblogs.com/ajanuw/p/10484605.html
Copyright © 2011-2022 走看看