Flutter 使用具有作用域模型的多个模型
Posted
技术标签:
【中文标题】Flutter 使用具有作用域模型的多个模型【英文标题】:Flutter Using Multiple Models with Scoped Model 【发布时间】:2019-04-15 10:50:24 【问题描述】:我正在尝试在 Flutter 中构建一个费用跟踪器应用程序,并决定使用 Scoped Model 进行状态管理。该应用程序有一个用户,他可以有多个帐户,每个帐户可以有多个交易。
如何对这些进行建模以与 Scoped Model 一起使用,我一直在选择一个好的架构。
如果我创建一个 UserModel,其中包含一个 Accounts 列表,其中每个 Account 都是一个 AccountModel,那么从 AccountModel 内部触发和更新将不会触发访问 UserModel 类的那些。
【问题讨论】:
为什么是"would not trigger"
?
【参考方案1】:
我有一个允许用户申请的搜索过滤器 UI: 排序 选择的类别 选择的位置(因为该应用是位置感知分类列表)
这 3 个过滤器触发对 REST API 的调用。过滤器菜单在 endDrawer(右侧导航抽屉)中管理,支架主体具有与未来构建器加载列表相关的列表视图
更好的例子是 GumTree app(https://play.google.com/store/apps/details?id=com.ebay.gumtree.au&hl=en)
我想坚持使用范围模型。我有 2 个存储库(类别和位置)与本地存储或 API 通信
我相信坚持范围模型来管理类别和位置是个好主意。
任何建议...
【讨论】:
如果这是一个问题,那么您应该考虑为此创建一个新主题【参考方案2】:让我们从一个主要问题开始。 作用域模型是 MVVM 吗? 我的回答是肯定的,如果实体必须保存在某个地方,就必须这样使用。
所以,我想在使用它两个月后很好地回答你。 在我看来,有两种可能性可以更抽象,而不必重新创建模型的结构,如果您不想在视图之间遇到数据管理问题,可以排除一种我见过的使用过的可能性。
第一个是经典:
Widget build(BuildContext context)
// At the top level of our app, we'll, create a ScopedModel Widget. This
// will provide the CounterModel to all children in the app that request it
// using a ScopedModelDescendant.
return ScopedModel<UserModel>( // <========
model: userModel,
child: ScopedModel<CounterModel>( // <========
model: counterModel,
child: MaterialApp(
title: 'Scoped Model Demo',
home: CounterHome('Scoped Model Demo'),
),
),
);
在我看来,第二个最聪明的方法是全局加载最重要的模型,以及仅用于某些视图(例如计时器)的模型,以便将它们插入要使用的页面的***别。
第二个例子是这样的: 在 main.dart 中
return ScopedModel<UserModel>(
model: UserModel(),
child: MaterialApp(
theme: ThemeData(
primaryColor: PrimaryColor,
),
home: new SplashScreen2(),
),
);
在锻炼.dart 中:
return ScopedModel<TimerModel>(
model: TimerModel(),
child: Scaffold(
child:Center(_widget)
),
);
现在,在您的 _widget 中,您可以使用 UserModel 和 TimerModel 的 ScopedModelDescendant..
我不建议你做的是创建一个混合的主模型并扩展所有其他模型。不幸的是,我看到了一些这样做的视频,但没有解释后果。或者,如果您想这样做,请确保它们之间没有链接,因为这可能会在真正应该更新的内容之间造成混淆 我建议您仅在有 2-3 个模型时才使用此解决方案。
我希望我对想知道如何使用它的人有所帮助
【讨论】:
【参考方案3】:class CombinedWidget extends StatelessWidget
@override
Widget build(BuildContext context)
final username =
ScopedModel.of<UserModel>(context, rebuildOnChange: true).username;
final counter =
ScopedModel.of<CounterModel>(context, rebuildOnChange: true).counter;
return Text('$username tapped the button $counter times');
您可以在source 中查看完整示例。
【讨论】:
这与我使用的模式很接近。还将 ScopedModel以上是关于Flutter 使用具有作用域模型的多个模型的主要内容,如果未能解决你的问题,请参考以下文章