【问题标题】:Flutter Persistence: how to jsonDecode a List<dynamic> to List<ClassType>?Flutter Persistence:如何将 List<dynamic> jsonDecode 为 List<ClassType>?
【发布时间】:2021-04-16 14:42:01
【问题描述】:

我有一个任务类的待办事项列表应用程序。 我想用 jsonEncode 序列化一个任务列表并将它们保存到 Docs 目录中的一个文件中。 之后,我希望能够重新序列化同一个列表并将它们转换为我的本机 List 数据类型(来自我从 jsonDecode 获得的 List)。最好的方法是什么?

目前,我尝试过:

void reSerializeTaskList() async {
    final directory = await getApplicationDocumentsDirectory();
    File f = File('${directory.path}/new.txt');
    String fileContent = await f.readAsString();
    List<dynamic> jsonList = jsonDecode(fileContent).cast<Task>(); // does not  work
    print("JSONSTRING: ${jsonList.runtimeType}");
    print("$jsonList");
  }

I/flutter (29177): JSONSTRING: CastList<dynamic, Task>
E/flutter (29177): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Task' in type cast

我的解决方法是遍历所有数组元素,并在我的 Task 类中使用“fromJson”方法从值中构建一个 Task 类型:

  void reSerializeTaskList() async {
    final directory = await getApplicationDocumentsDirectory();
    File f = File('${directory.path}/new.txt');
    String fileContent = await f.readAsString();
    List<dynamic> jsonList = jsonDecode(fileContent);

    List<Task> taskList = [];
    for (var t in jsonList) {
      print("T: $t and ${t.runtimeType}");
      Task task = new Task();
      taskList.add(task.fromJson(t));
    }
    print("JSONSTRING: ${jsonList.runtimeType}");
    print("$jsonList");

    print("$taskList");
    print("$taskList.runtimeType");
  } 

我的任务类:

import 'dart:io';

class Task {
  String name;
  bool isDone;

  Task({this.name, this.isDone = false});

  void toggleDone() {
    isDone = !isDone;
  }

  @override
  String toString() {
    // TODO: implement toString
    return "${this.name} is done: $isDone";
  }

  Map<String, dynamic> toJson() {
    return {
      "name": this.name,
      "isDone": this.isDone,
    };
  }

  Task fromJson(Map<String, dynamic> json) {
    this.name = json['name'];
    this.isDone = json['isDone'];
    return this;
  }
}

但是可能有另一种(更好的)方法吗?这对我来说看起来很不完整......

【问题讨论】:

    标签: json flutter asynchronous serialization persistence


    【解决方案1】:

    举个小例子,我就是这样做的

    final jsonResponse = json.decode(jsonString);
            final List<Customer> customers = jsonResponse.map<Customer>((jR) => Customer.fromJson(jR)).toList();
    

    Customer 类中的 fromJson 看起来像这样

      factory Customer.fromJson(Map<String, dynamic> json) => Customer(
        id: json["id"] == null ? null : json["id"],
        changeDate: json["changeDate"] == null ? null : DateTime.parse(json["changeDate"]),
        name: json["name"] == null ? null : json["name"],
      );
    

    【讨论】:

    • 感谢这个工作并且看起来更好,但是我的方法 Task fromJson(Map json) 和你的方法 factory Task.fromJson... 的区别在哪里?对该语法还不太了解..
    • 工厂避免创建新实例。我想我也像你一开始那样做,但由于所有例子都使用工厂,我换了(所以个人没有经历过缺点)。 5 月的重点是第一个带有 .map 的 sn-p
    • 当它回答你的问题时,接受答案将是一个很好的姿态:-)
    猜你喜欢
    • 2020-08-03
    • 2021-05-27
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 2021-05-20
    • 2020-09-04
    相关资源
    最近更新 更多