针对特定用例在不同页面上保持相同状态

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 小部件,每次发生变化时都会更新。

以上是关于针对特定用例在不同页面上保持相同状态的主要内容,如果未能解决你的问题,请参考以下文章

Jmeter 为两个不同的用例在图中定义 X 轴值

Boost.Interprocess:测试用例在编译时有或没有优化(GCC)会给出不同的结果

org.openqa.selenium.NoSuchElementException 即使元素存在

如何通过单击放置在同一页面上的小部件来显示不同的小部件

在AngularJS中清除工厂状态变化的最佳实践(1.x)

重用具有不同样式的 React 组件