针对特定用例在不同页面上保持相同状态
Posted
技术标签:
【中文标题】针对特定用例在不同页面上保持相同状态【英文标题】:Maintaining same state on different pages in flutter for a particular use case 【发布时间】:2020-10-28 12:11:19 【问题描述】:我知道在 Flutter 中存在一些关于状态管理的问题,但似乎都没有解决我的用例。
最近我正在构建一个基于电子商务的应用程序,并且遇到了对状态管理的真正需求。 我有 2 页,
-
一个是产品页面,我在其中将产品添加到购物车。
第二个是购物车页面,我可以在其中看到最近添加到购物车的产品。
用户可以将产品添加到购物车,然后导航到购物车。在购物车页面中,他们还可以增加或减少商品的数量。
如您所见,最初黄色商品以数量 3 添加到购物车中,但在购物车页面中,用户按下 (-) 按钮并将数量减少为 1。现在如果用户按下后退按钮,那么黄色产品的状态在产品页面上仍然是 3。粉红色产品的情况类似。
因此,我尝试使用普通的 setState 和一些全局数据结构来跟踪数量来解决这个问题。但是随着我的应用程序变大,跨页面维护状态真的很困难。 我已经阅读了不同的状态管理解决方案,如 redux、BloC 模式、Provider ......但我不清楚如何在我的用例中使用它们中的任何一个。 有没有经验的大神,把石头打碎,帮我消化一下?
任何有关如何解决此问题的示例代码和解释都将不胜感激!
希望我的问题很清楚!
【问题讨论】:
【参考方案1】:ANUP SAJJAN 要实现这一点,您可以使用 Provider 包。根据您的情况查看这些代码示例:
import 'package:flutter/material.dart';
import 'models/cartmodel.dart';
class AppState with ChangeNotifier
List<CartModel> _cartModel = new List<CartModel>();
// Cart data list
List<CartModel> get getCart => _cartModel;
// Add item to cart
addToCart(CartModel value)
_cartModel.add(value);
notifyListeners();
// Remove item to cart
removeToCart(CartModel value)
_cartModel.remove(value);
notifyListeners();
在main.dart
中创建实例:
runApp(
ChangeNotifierProvider<AppState>(
create: (_) => AppState(),
child: MyApp(),
),
)
您现在可以控制状态:
@override
Widget build(BuildContext context)
final appState = Provider.of<AppState>(context);
...
// manipulation
appState.getCart
appState.addToCart(value)
appState.removeToCart(value)
...
【讨论】:
感谢@Hakiza,我对提供者比较陌生。但据我想象,我有一个产品列表,我的代码库在每个产品上都有 onTap 侦听器,用于递增和递减。那么,您的代码如何与每个产品的聆听变化相关联?我的意思是,当每个产品发生变化时,您是否订阅接收通知? 基本上,您如何在“产品页面”和“购物车页面”中链接黄色产品以保持相同的状态? 商品列表与购物车的列表确实不一样;在购物车中,您需要产品 ID 和数量。当处理递增或递减监听器时,AppState 类将通知订阅者(页面)的所有更改。您可以使用与上述产品列表示例相同的方式。【参考方案2】:状态实际上是控制一个屏幕状态的工具,而不是数据存储。在这种情况下,您可能不应该使用 State,而应该使用数据库。当用户编写他们的购物车时,您可以在用户的设备 SQLite 或云端(Firebase?)中创建购物车记录。起初这可能看起来有点过头,但考虑到除了拥有可以从任何地方访问的持久存储之外,您还可以获得用户行为数据,即他们添加了什么、他们如何进行以及有多少人离开。
至于技术方面,在 Flutter 中使用 Providers 是很常见的。对我来说,最大的好处是业务逻辑封装。否则,您的特定数据库逻辑将遍布表示层,如果您想更改某些内容,您将遇到麻烦:)
这里是一个关于供应商的good article。
【讨论】:
我同意通过使用数据库或云,您可以深入了解用户行为。但是这里的问题是,如果他从购物车返回到产品页面,那么状态应该会更新,当我有大约 1000 多个产品时,要跟踪所有产品并找到关系会很麻烦,不是吗? ? 并非如此。每个产品都有一个 id,所以您需要做的就是在购物车中存储产品 id 和数量的列表。购物车还应包含用户(或会话)ID,以便为当前用户提供正确的购物车。 好吧,可以说每个产品的数据库中都存在新的更新数量,但是当用户按下购物车中的后退按钮时,产品页面会从导航堆栈打开,显示旧状态本身。现在如何更新新数量? 对于持续更新,您需要一个 Stream 和一个 Streambuilder 小部件,每次发生变化时都会更新。以上是关于针对特定用例在不同页面上保持相同状态的主要内容,如果未能解决你的问题,请参考以下文章
Boost.Interprocess:测试用例在编译时有或没有优化(GCC)会给出不同的结果