一个强大的状态机,用于 MobX 管理,几乎可以用于任何应用程序状态。
它有3种状态——加载中、成功、错误——非常适合用于无限列表、操作按钮、闪光效果、刷新逻辑等。
特点
要求
此包仅与 MobX 配合使用。最低 Dart SDK 版本为 2.16。
用法
简单状态
用于处理简单的逻辑,例如显示字符串列表。
在mobx控制器文件中创建DataState
final dataState = DataState<List<String>>();
Future<void> fetchData() async {
dataState.setLoadingState();
try {
final data = await Future.delayed(const Duration(seconds: 3))
.then((_) => ['String 1', 'String 2', 'String 3']);
dataState.setSuccessState(data);
} catch (e) {
dataState.setErrorState(e);
}
}
然后,在视图中添加Observer来展示列表
final controller = ControllerInstance();
@override
void initState() {
fetchData();
//...
super.initState();
}
@override
Widget build(context) {
//...
Observer(
builder: (context) => controller.dataState.handleState(
loading: () {
return const CircularProgressIndicator();
},
success: (data) {
return ListView.builder(
shrinkWrap: true,
itemCount: data.length,
itemBuilder: (context, index) => Text(
data[index],
textAlign: TextAlign.center,
),
);
},
error: (error) {
return const Text('Error');
},
),
),
}
在此处查看完整的代码 here。
可重载状态
当您想在加载小部件回调中使用数据时,请使用handleStateLoadableWithData方法。例如,在无限列表或刷新逻辑中。
Observer(
builder: (context) => controller.dataState.handleStateLoadableWithData(
loading: (data) {
return Stack(
children: [
if (data != null) list(data),
Positioned.fill(
child: Container(
color: Colors.black45,
alignment: Alignment.center,
child: const CircularProgressIndicator()),
),
],
);
},
success: (data) => list(data),
error: (error) {
return const Text('Error');
},
),
);
在此处查看完整的示例代码 here。
使用reaction的状态
要仅在状态更改后处理一次状态,handleReactionState是解决方案。只需在initState中设置,并记住在dispose方法中处理它。
例如,显示一个完整的对话框
List<ReactionDisposer>? reactionsDisposers;
@override
void initState() {
reactionsDisposers = [
controller.dataState.handleReactionState(
loading: loadingDialog,
)
];
super.initState();
}
@override
void dispose() {
reactionsDisposers?.forEach((dispose) {
dispose();
});
super.dispose();
}
void loadingDialog(bool show) {
if (show) {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return Dialog(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CircularProgressIndicator(),
SizedBox(width: 32),
Text("Loading"),
],
),
),
);
},
);
} else {
Navigator.of(context).pop();
}
}
在此处查看完整的示例代码 here。