在搜索并了解有关如何添加或更新数据结构的某些字段的更多信息后,我们有以下实现
在这里,我们希望有一个简单order
的数据结构,用户可以将服务添加到订单或更新选定的服务计数,例如,在第一次用户没有选择任何服务时,我们将OrderStructure:[]
其初始化为constructor
:
OrderNotifier() : super(_initial);
static OrderStructure _initial = OrderStructure('', []);
当用户选择任何服务时,我们将三个参数传递给increment
方法:
void increment({required int productId, required int serviceId, required int serviceCost})
如果服务不存在,则应添加属于产品的服务。每个服务都属于产品,我们将其与 productId 存储在increment
我们传递的方法中productId
,serviceId
和serviceCost
,它可以搜索到类数据结构中作为 OrderStructure。
如果 productId 存在,那么我们尝试搜索 serviceId,如果 serviceId 存在。productId = true && serviceId = true
那么我们应该增加count
值,如果它不存在,它应该保存为新项目,注意我们不应该有多个相同productId
或serviceId
进入OrderStructure
。
它们中的每一个都必须是唯一的。每个产品可以有多个服务,例如List
,OrderStructure
不应该有多个productId
例如OrderStructure
数据结构可以是:
OrderStructure:
title : 'sample',
products:[
productId: 1
services : [
[serviceId:1, count:1, cost: 100],
[serviceId:2, count:9, cost: 500],
[serviceId:3, count:5, cost: 2000],
],
productId: 2
services : [
[serviceId:3, count:10, cost: 100],
[serviceId:5, count:6, cost: 500]
],
productId: 3
services : [
[serviceId:3, count:10, cost: 100],
[serviceId:5, count:6, cost: 500],
[serviceId:6, count:6, cost: 500],
[serviceId:7, count:6, cost: 500],
[serviceId:8, count:6, cost: 500],
],
]
当用户选择seriveId
id1
并且productId
id 是1
时,我们在这个集合中搜索productId
然后serviceId
,如果它存在则count
应该增加,否则应该OrderStructure
作为一个新的添加到集合中
例如:
OrderStructure:
title : 'sample',
products:[
productId: 1
services : [
[serviceId:1, count:2, cost: 100],
...
我们有这段代码,但它不正确:
void increment({required int productId, required int serviceId, required int serviceCost}) {
final newState = OrderStructure(state.title, [
...state.products,
for (final product in state.products)
if (product.id == productId)
for (final service in product.services)
if (service.id == serviceId)
SelectedProducts(productId,
[...product.services, SelectedProductServices(service.id, service.count + 1, service.cost)])
]);
// ignore: iterable_contains_unrelated_type
if (!newState.products.contains(productId) ||
// ignore: iterable_contains_unrelated_type
!newState.products.firstWhere((p) => p.id == productId).services.contains(serviceId)) {
newState.products.add(
SelectedProducts(serviceId, <SelectedProductServices>[SelectedProductServices(serviceId, 1, serviceCost)]));
}
state = newState;
}
完整代码:
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends ConsumerWidget {
@override
Widget build(BuildContext context,ScopedReader watch) {
final _orderProvider = watch(orderStateNotifierProvider.notifier);
final _product = SelectedProducts(1, []);
final _service = SelectedProductServices(1, 1, 111);
return Scaffold(
appBar: AppBar(
title: Text('test'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
TextButton(
child: Text('add new service'),
onPressed: ()=>context.read(orderStateNotifierProvider.notifier)
.increment(productId:1, serviceId:1, serviceCost:100),
),
// here we want to add new service to product, the same as above code, if productId doesn't exists
// into `OrderStructure` it should be save with
TextButton(
child: Text('append service to product`s services'),
onPressed: ()=>context.read(orderStateNotifierProvider.notifier)
.increment(productId:1, serviceId:2, serviceCost:500),
),
Text('product`s service count: ${_orderProvider.state.products[0].services.length}')
],
),
)
);
}
}
//------------------------
final orderStateNotifierProvider = StateNotifierProvider<OrderNotifier, OrderStructure>((ref) => OrderNotifier());
class OrderNotifier extends StateNotifier<OrderStructure> {
OrderNotifier() : super(_initial);
static OrderStructure _initial = OrderStructure('', []);
void resetOrder() {
_initial = const OrderStructure('', []);
}
void updateAddress({
required String title,
}) {
state = OrderStructure(title,state.products);
}
void increment({required int productId, required int serviceId, required int serviceCost}) {
final newState = OrderStructure(state.title, [
...state.products,
for (final product in state.products)
if (product.id == productId)
for (final service in product.services)
if (service.id == serviceId)
SelectedProducts(productId,
[...product.services, SelectedProductServices(service.id, service.count + 1, service.cost)])
]);
// ignore: iterable_contains_unrelated_type
if (!newState.products.contains(productId) ||
// ignore: iterable_contains_unrelated_type
!newState.products.firstWhere((p) => p.id == productId).services.contains(serviceId)) {
newState.products.add(
SelectedProducts(serviceId, <SelectedProductServices>[SelectedProductServices(serviceId, 1, serviceCost)]));
}
state = newState;
}
}
class OrderStructure {
final String title;
final List<SelectedProducts> products;
const OrderStructure(this.title, this.products);
}
class SelectedProducts {
final int id;
final List<SelectedProductServices> services;
SelectedProducts(this.id, this.services);
}
class SelectedProductServices {
final int id;
final int count;
final int cost;
const SelectedProductServices(this.id, this.count, this.cost);
}