前言
Dio 系列文章第二篇,之前一篇讲述了 Dio 的基本介绍和获取列表数据的实例,文章链接如下:
本篇介绍如何使用 Dio 提供的 delete
方法对接后台的删除接口。调试前需要启动后台工程,参考上一篇文章,运行后台应用(同时应准备好后台数据库数据)。
界面交互
我们需要实现长按弹出列表元素来进行删除操作,界面实现不是本篇的重点,上 pub 找了一个 FocusedMenu来实现。FocusedMenu 实现比较简单,我们只需要将列表元素使用 FocusedMenuHolder 包裹起来即可:
// dynamic_item.dart
@override
Widget build(BuildContext context) {
return FocusedMenuHolder(
child: Container(
// 省略原列表元素构建代码
),
onPressed: () {
// 点击事件
_handlePressed(context);
},
// 长按菜单
menuItems: <FocusedMenuItem>[
FocusedMenuItem(
title: Text("查看详情"),
trailingIcon: Icon(Icons.remove_red_eye_outlined),
onPressed: () {
_handlePressed(context);
}),
FocusedMenuItem(
title: Text("取消"),
trailingIcon: Icon(Icons.cancel),
onPressed: () {},
),
FocusedMenuItem(
title: Text(
"删除",
style: TextStyle(color: Colors.redAccent),
),
trailingIcon: Icon(
Icons.delete,
color: Colors.redAccent,
),
onPressed: () {
handleDelete(dynamicEntity.id);
}),
],
);
}
关键是长按菜单的配置,配置对应的菜单名称、图标、响应事件即可。这里的 handleDelete 方法从列表页面传递过来,接收一个列表元素的 id,以便在列表页面处理删除的逻辑。
网络请求删除实现
在dynamic_service.dart 中增加一个删除方法,用于网络请求删除,如下所示:
static Future delete(String id) async {
var result = await Dio().delete(
host + 'dynamics/' + id,
);
return result;
}
方法很简单,只需要调用 Dio 实例的删除方法,将需要删除的 id
拼接上 url
地址即可。
对应的调用的业务代码如下,当点击弹出菜单的删除按钮时调用该方法。该方法如果删除成功(状态码200),则从当前列表中移除该元素,并刷新状态更新界面;如果失败(状态码为其他),则通过 SnackBar 显示错误信息。
void _onItemDelete(String id) async {
try {
var response = await DynamicService.delete(id);
if (response.statusCode == 200) {
setState(() {
_listItems.removeWhere((element) => element.id == id);
});
} else {
_showErrorInfo(this.context, response.statusMessage);
}
} on DioError catch (e) {
_showErrorInfo(this.context, e.message);
} catch (e) {
_showErrorInfo(this.context, e.toString());
}
}
这里首先是使用了一个 try...catch
包裹了网络请求,这是因为后台可能发生异常,例如数据已经被删除了,后台存在 bug
等等。目前我们还没有做统一对 Dio的异常进行处理,因此为了防止后台异常导致应用崩溃有必要做异常捕获。实际可以传一个虚拟的 id 验证异常,会发现Dio 会抛出一个 DioError
错误出来,这里我们可以向用户提示错误信息。
顺带讲一下 Dart 的异常捕获形式,可以看到有个on
关键字,这里可以使用多个 on
来匹配不同的异常。形式如下,其中catch
的第二个参数是堆栈信息。
try {
// ...
} on ExceptionType1 catch (e) {
// ExceptionType1异常处理
} on ExceptionType2 catch (e) {
// ExceptionType2异常处理
} catch (e,s) {
// 其他异常处理
}
运行效果
运行效果如下图(第二张为捕获异常的情况):
源码
源码地址:https://gitee.com/island-coder/flutter-beginner/tree/master/network
欢迎关注个人公众号:岛上码农