推荐的数据流(导入/导出)

时间:2019-11-29 20:50:38

标签: flutter dart

我有一个flutter应用程序,(简单地说)可以在各种屏幕上列出一些数据,并且可以对其进行修改。我当前的数据方法可行,但我认为这不是最佳实践或最佳实践。

当前,保存对象时,会将其转换为JSON(使用dart:convert)并存储在设备上的文件中(使用dart.io),并覆盖该文件(如果存在)。需要显示这些对象的每个屏幕都会读取文件以获取对象。每次需要保存更改时,它都会再次导出所有内容(覆盖),然后再次导入以显示它。

我选择JSON而不是S的原因是因为我想稍后添加Web部分。这种读/写方法是否是最佳实践?我觉得对大多数屏幕的所有数据进行如此大量的读/写操作可能会导致一些性能问题。

任何建议都值得赞赏!

1 个答案:

答案 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';
});

请记住,此代码仅显示概念的工作方式。您需要根据情况进行更改。您还可以决定不公开data1Inputupdate(...)函数,这取决于您自己的设计。


1 我个人使用的是BloC,您的情况可能需要使用其他方式。