flutter - 如何在 Riverpod 中显示来自 StateNotifier 的小吃店?
问题描述
我有以下工作正常的课程。
class CartRiverpod extends StateNotifier<List<CartItemModel>> {
CartRiverpod([List<CartItemModel> products]) : super(products ?? []);
void add(ProductModel addProduct) {
bool productExists = false;
for (final product in state) {
if (product.id == addProduct.id) {
print("not added");
productExists = true;
}
else {
}
}
if (productExists==false)
{
state = [
...state, new CartItemModel(product: addProduct),
];
print("added");
}
}
void remove(String id) {
state = state.where((product) => product.id != id).toList();
}
}
上面的代码完美运行。在我的购物车中,我想将产品的订单限制为 1 个单位,这就是我执行上面代码的原因。它按我的预期工作。现在唯一的事情是,我想显示一个快餐栏,提醒用户他或她只能订购每种产品的 1 个单位。
如何在我的 StateNotifier 中添加快餐栏?
解决方案
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/all.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'cart_list_page.freezed.dart';
final cartListPageStateNotifierProvider =
StateNotifierProvider((ref) => CartListPageStateNotifier(ref.read));
final cartListProvider = StateProvider((ref) {
return <CartListItemModel>[];
}); // this holds the cart list, at initial, its empty
class CartListPage extends StatefulWidget {
@override
_CartListPageState createState() => _CartListPageState();
}
class _CartListPageState extends State<CartListPage> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
List<CartListItemModel> productsToBeAddedToCart = [
CartListItemModel(id: 1, name: "Apple"),
CartListItemModel(id: 2, name: "Tomatoes"),
CartListItemModel(id: 3, name: "Oranges"),
CartListItemModel(id: 4, name: "Ginger"),
CartListItemModel(id: 5, name: "Garlic"),
CartListItemModel(id: 6, name: "Pine"),
];
@override
Widget build(BuildContext context) {
return ProviderListener<CartListState>(
provider: cartListPageStateNotifierProvider.state,
onChange: (context, state) {
return state.maybeWhen(
loading: () {
final snackBar = SnackBar(
duration: Duration(seconds: 2),
backgroundColor: Colors.yellow,
content: Text('updating cart....'),
);
return _scaffoldKey.currentState.showSnackBar(snackBar);
},
success: (info) {
final snackBar = SnackBar(
duration: Duration(seconds: 2),
backgroundColor: Colors.green,
content: Text('$info'),
);
_scaffoldKey.currentState.hideCurrentSnackBar();
return _scaffoldKey.currentState.showSnackBar(snackBar);
},
error: (errMsg) {
final snackBar = SnackBar(
duration: Duration(seconds: 2),
backgroundColor: Colors.red,
content: Text('$errMsg'),
);
_scaffoldKey.currentState.hideCurrentSnackBar();
return _scaffoldKey.currentState.showSnackBar(snackBar);
},
orElse: () => SizedBox.shrink(),
);
},
child: Scaffold(
key: _scaffoldKey,
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
children: [
SizedBox(height: 40),
Expanded(
child: ListView.builder(
itemCount: productsToBeAddedToCart.length,
itemBuilder: (context, index) {
final item = productsToBeAddedToCart[index];
return ListTile(
title: Text("${item.name}"),
leading: CircleAvatar(child: Text("${item.id}")),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.add),
onPressed: () => context
.read(cartListPageStateNotifierProvider)
.addProduct(item),
),
SizedBox(width: 2),
IconButton(
icon: Icon(Icons.remove),
onPressed: () => context
.read(cartListPageStateNotifierProvider)
.removeProduct(item),
),
],
),
);
},
),
)
],
),
),
),
);
}
}
class CartListPageStateNotifier extends StateNotifier<CartListState> {
final Reader reader;
CartListPageStateNotifier(this.reader) : super(CartListState.initial());
addProduct(CartListItemModel product) async {
state = CartListState.loading();
await Future.delayed(Duration(seconds: 1));
var products = reader(cartListProvider).state;
if (!products.contains(product)) {
reader(cartListProvider).state.add(product);
return state =
CartListState.success("Added Successfully ${product.name}");
} else {
return state = CartListState.error(
"cannot add more than 1 product of the same kind");
}
}
removeProduct(CartListItemModel product) async {
state = CartListState.loading();
await Future.delayed(Duration(seconds: 1));
var products = reader(cartListProvider).state;
if (products.isNotEmpty) {
bool status = reader(cartListProvider).state.remove(product);
if (status) {
return state =
CartListState.success("removed Successfully ${product.name}");
} else {
return state;
}
}
return state = CartListState.error("cart is empty");
}
}
@freezed
abstract class CartListState with _$CartListState {
const factory CartListState.initial() = _CartListInitial;
const factory CartListState.loading() = _CartListLoading;
const factory CartListState.success([String message]) = _CartListSuccess;
const factory CartListState.error([String message]) = _CartListError;
}
@freezed
abstract class CartListItemModel with _$CartListItemModel {
factory CartListItemModel({final String name, final int id}) =
_CartListItemModel;
}
推荐阅读
- javascript - 从给定概率的有限选项集中伪随机选择
- windows - 发布时 IIS 服务器上的 400 错误请求
- html - 如何创建此徽标效果(覆盖背景 div 颜色的透明边框)
- android - 从后台线程调用 startActivity 并且主线程被阻塞时,活动延迟启动
- angular - ngx-bootstrap ,组件模态,选择器“modal-content”没有匹配任何元素
- azure - 数据工厂中的管道正在加载部分数据
- javascript - javascript在一个函数中多次返回
- php - mPDF 中使用的默认日文字体
- r - R - 动画图(gganimate) - 我可以订购 Y 轴吗?
- node.js - 如何管理两个 API 之间的用户令牌并使请求有效?