Flutter 中的多页面状态处理
Posted
技术标签:
【中文标题】Flutter 中的多页面状态处理【英文标题】:State handeling in Flutter with multiple pages 【发布时间】:2020-03-17 20:14:15 【问题描述】:我正在尝试找出一种构建 Flutter 应用程序的好方法。我有几个页面,可以导航到其他页面。一页修改的数据,可能会被其他页使用,需要更新。我最近开始使用 Provider 包。我让每个页面都有一个实现 ChangeNotifier 的模型,并在 MaterialApp 上方设置了一个 ChangeNotifierProvider。现在要更新其他页面的数据,我必须获取其他页面的模型并在其上调用更新方法。这很乱。我使用 Firestore,所以我可以监听数据库的变化,但我想避免太多的魔法。此外,有时只将数据从一个页面发送到另一个页面而不使用网络调用,或者在 Navigator.pop 方法中将数据传回是有意义的。我发现很难在如何解决这个问题上做出好的选择。我可能应该看看更精致的架构,比如 redux 或 mobx。或者只是选择一个普通的解决方案,并为所有各种事件使用大量回调。每页那些big'ol模型,一段时间后似乎有点臃肿和凌乱。有没有人在 Flutter 方面有类似的经验如何构建这些东西? 困惑
【问题讨论】:
【参考方案1】:使用provider 应用BLoC
模式并将其与RxDart 结合是解决此问题的一种方法。
例如,您可以创建一个AppBloc
:
class AppBloc
StreamController<UserInputState> _userInputController =
BehaviorSubject<UserInputState>.seeded(UserInputState('NOTHING'));
StreamSink<UserInputState> get userInputSink => _userInputController.sink;
Observable<UserInputState> get userInputObs => Observable(_userInputController.stream);
AppBloc();
class UserInputState
final String input;
const UserInputState(this.input);
在一个页面上你可以通过它传递数据:
final appBloc = Provider.of<AppBloc>(context);
appBloc.userInputSink.add(UserInputState("input"));
另外一个页面可以监听数据:
final appBloc = Provider.of<AppBloc>(context);
appBloc.userInputObs.
.where((state) => state.input == "input")
.listen((state) => /* do something */);
我在这里对其进行了简化,但是这种可以是一种以反应方式处理数据的非常健壮的方式。
美妙之处在于您可以将Observable
绑定到StreamBuilder(Flutter 的一部分)以使 UI 也具有响应性!
【讨论】:
为什么需要 Observable?难道你不能只获得其他人可以收听的广播流吗? @Erlend 一个Observable
是一个使用类固醇的Stream
。它只是扩展了Stream
并添加了许多有用的功能。更多详情请见here。
谢谢。我想我会考虑使用流来解决我的状态问题,也许会想出一个自定义的解决方案。我会接受你的回答,因为我的问题有点泛滥。我还发现了以下repo 和video,我觉得这很有趣。
@Erlend 是的,github repo 展示了一个有趣的概念!我通常会建议至少在使用像 ObservableState
这样的抽象之前玩一下 vanilla 流/rxdart。我还将StreamController
、StreamSink
和Observable
封装到我自己的自定义类中,这样它们就更容易用于我自己的用例了。
刚开始使用流、dartrx 和 BehaviorSubject,结合 StreamBuilder,真是太好了!!【参考方案2】:
使用 Provider(或任何实现 BloC 模式的库)和存储库模式应该可以在本地移动/存储数据。基本上,每个 Bloc/Provider 都会获取存储库的一个实例并对其进行读/写值。由于存储库实例始终相同,因此您将更新所有数据。
此外,您可以使用本地数据库,例如 SQLite(带有 sqflite 包)或纯 NoSQL 数据库的 Hive。
我个人不喜欢 Redux,但 mobx 是一个非常好的选择。
【讨论】:
以上是关于Flutter 中的多页面状态处理的主要内容,如果未能解决你的问题,请参考以下文章
Flutter:未处理的异常:错误状态:DocumentSnapshotPlatform中不存在字段