我有一个任务模型 =>
class Task {
Task({this.isDone,this.name,this.time,this.priorityValue});
final String name;
bool isDone;
final DateTime time;
int priorityValue;
factory Task.fromJson(Map<String, dynamic> jsonData) {
return Task(
name: jsonData['name'],
isDone: false,
time: jsonData['time'],
priorityValue: jsonData['priorityValue'],
);
}
toJSONEncodable() {
Map<String, dynamic> m = new Map();
m['name'] = name;
m['isDone'] = isDone;
m['time'] = time;
m['priorityValue'] = priorityValue;
return m;
}
static Map<String, dynamic> toMap(Task task) => {
'name': task.name,
'isDone': task.isDone,
'time': task.time,
'priorityValue': task.priorityValue,
};
}
并且当使用 localStorage 包保存一些对象列表时,我收到此错误 =>
(Flutter) 未处理的异常:将对象转换为可编码对象失败:'DateTime' 实例
_saveToStorage() {
storage.setItem('tasks', list.toJSONEncodable());
print("Saved");
}
我尝试使用 .toString() 但后来我得到这个错误 => 类型 'String' 不是类型 'index' 的 'int' 的子类型
有什么想法可以在 LocalStorage 包上保存日期时间吗?
更新:
factory Task.fromJson(Map<String, dynamic> jsonData) {
return Task(
name: jsonData['name'],
isDone: false,
time: jsonData["time"] == null ? null : DateTime.parse(jsonData["time"]),
priorityValue: jsonData['priorityValue'],
);
}
toJSONEncodable() {
Map<String, dynamic> m = new Map();
m['name'] = name;
m['isDone'] = isDone;
m['time'] = time == null ? null : time.toIso8601String();
m['priorityValue'] = priorityValue;
return m;
}
static Map<String, dynamic> toMap(Task task) => {
'name': task.name,
'isDone': task.isDone,
'time': task.time,
'priorityValue': task.priorityValue,
};
var items = storage.getItem('tasks');
if (items != null) {
list.items = List<Task>.from(
(items as List).map(
(item) => Task(
name: item['name'],
isDone: item['isDone'],
time: DateTime.parse(item['time']),
priorityValue: items['priorityValue'],
),
),
);
}
更新后我收到此错误“类型'字符串'不是'索引'的'int'类型的子类型”
更新 2:
var items = storage.getItem('tasks');
if (items != null) {
final decodedJson = jsonDecode(items);
list.items = (decodedJson as List)
.map((e) => Task.fromJson(e))
.toList();
final task = list.items.first;
print("${task.name}");
// list.items = List<Task>.from(
// (items as List).map(
// (item) => Task(
// name: item['name'],
// isDone: item['isDone'],
// time: DateTime.parse(item['time']),
// priorityValue: items['priorityValue'],
// ),
// ),
// );
}
在第二次更新后,我得到“类型 '_InternalLinkedHashMap
已修复
我将模型中的 DaeTme 改为字符串,并在得到它时将时间转换为字符串
"${selectedDate.toLocal()}".split(' ')[0]
答案 0 :(得分:0)
使用 toJson
"changeDate": changeDate == null ? null : changeDate.toIso8601String(),
和 fromJson
changeDate: json["changeDate"] == null ? null : DateTime.parse(json["changeDate"]),
答案 1 :(得分:-1)
我强烈建议您使用 Retrofit 和 json_serializable 来描述您的 API
它可能看起来像这样:
import 'package:json_annotation/json_annotation.dart';
part 'task.g.dart';
@JsonSerializable(nullable: false, explicitToJson: true)
class Task {
final String name;
bool isDone;
final DateTime time;
int priorityValue;
Task({this.isDone, this.name, this.time, this.priorityValue});
factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
Map<String, dynamic> toJson() => _$TaskToJson(this);
}
之后你需要运行build_runner
:
flutter pub run build_runner build
它会毫不费力地生成 toJson
和 fromJson
方法:
Task _$TaskFromJson(Map<String, dynamic> json) {
return Task(
isDone: json['isDone'] as bool,
name: json['name'] as String,
time: DateTime.parse(json['time'] as String),
priorityValue: json['priorityValue'] as int,
);
}
Map<String, dynamic> _$TaskToJson(Task instance) => <String, dynamic>{
'name': instance.name,
'isDone': instance.isDone,
'time': instance.time.toIso8601String(),
'priorityValue': instance.priorityValue,
};
您可以查看测试:
void main() {
test('Task should be parsed from json', () {
const json = '''
[
{
"name": "testing",
"isDone": false,
"time": "2021-01-12T13:57:10.705476",
"priorityValue": 0
}
]
''';
final List decodedJson = jsonDecode(json);
final List<Task> list = decodedJson.map((e) => Task.fromJson(e)).toList();
final Task task = list.first;
expect(task.name, 'testing');
expect(task.isDone, false);
expect(task.time, DateTime.parse("2021-01-12T13:57:10.705476"));
expect(task.priorityValue, 0);
});
}