我有一个flutter应用程序,(简单地说)可以在各种屏幕上列出一些数据,并且可以对其进行修改。我当前的数据方法可行,但我认为这不是最佳实践或最佳实践。
当前,保存对象时,会将其转换为JSON(使用dart:convert
)并存储在设备上的文件中(使用dart.io
),并覆盖该文件(如果存在)。需要显示这些对象的每个屏幕都会读取文件以获取对象。每次需要保存更改时,它都会再次导出所有内容(覆盖),然后再次导入以显示它。
我选择JSON而不是S的原因是因为我想稍后添加Web部分。这种读/写方法是否是最佳实践?我觉得对大多数屏幕的所有数据进行如此大量的读/写操作可能会导致一些性能问题。
任何建议都值得赞赏!
答案 0 :(得分:1)
当对数据模型/设置进行更改时,这是一种将数据保留在内存中并写入磁盘的可能方法。
我自己使用RxDart。尽管它确实使生活更轻松,但您实际上并不需要它。我将简化下面的示例,以便您了解该概念并将其应用于您自己的需求。
假设您在设置类中跟踪数据:
@JsonSerializable()
class Settings {
String someData1;
String someData2;
// json seriazable functions
}
您需要一个“处理程序” 1 或类似的东西来管理对Settings
所做的更改以及读取/写入数据:
class SettingsHandler {
Settings _settings;
StreamController<Settings> _settingsController = BehaviorSubject<Settings>();
StreamController<String> _data1Controller = BehaviorSubject<String>();
StreamSink<String> get data1Input => _data1Controller.sink;
Observable<String> get data1Output => Observable(_data1Controller.stream);
Future<Settings> _readFromDisk() async {
// do your thing
}
Future<Settings> _writeToDisk(Settings settings) async {
// do your thing
}
Future<void> init() async {
// read from disk
_settings = await _readFromDisk();
_settingsController.sink.add(_settings);
// initialize data
data1Input.add(_settings.someData1);
data1Output
.skip(1) // we skip because we just added our initialization data above.
.listen((value) =>
// we must propagate through the update function
// otherwise nothing gets written to disk
update((settings) => settings.someData1 = value)
);
// when changes are made, it needs to notify this stream
// so everything can be written to disk
_settingsSaver.output
// save settings every 2.5 seconds when changes occur.
.debounceTime(const Duration(milliseconds: 2500))
// get the changes and write to disk
.listen((settings) => _writeToDisk(settings));
}
// this function is crucial as it allows changes to be made via the [adjustFunc]
// and then propagates this into the _settingsSaver stream.
void update(void Function(Settings input) adjustFunc) {
adjustFunc(_settings);
_settingsSaver.sink.add(_settings);
}
}
所以现在您可以做类似的事情
var handler = SettingsHandler();
await handler.init();
// this
handler.data1Input.add('NewData');
// or this
handler.update((settings) {
settings.someData1 = 'NewData';
});
请记住,此代码仅显示概念的工作方式。您需要根据情况进行更改。您还可以决定不公开data1Input
或update(...)
函数,这取决于您自己的设计。
1 我个人使用的是BloC,您的情况可能需要使用其他方式。