Flutter 用 Dio的 Patch请求完成数据编辑功能

简介: 本篇介绍了详情数据的获取,实体对象的部分修改来展示 Dio的 patch 请求。可以看到,Dio 提供的一系列 Restful 请求的方式基本相同,可以做到更好的封装。

前言

本篇介绍表单更新请求,利用 Patch 请求更新动态数据,需要做得准备工作如下:

  • 拉取后台新的代码,项目地址:后台源码,拉到本地后,在项目目录运行 node seed.js 生成测试数据。
  • 运行后台应用:在项目目录node index.js 即可运行后台接口应用,项目默认接口地址为:http://localhost:3900/api/

整理代码

回顾一下上一篇的代码,发现上一篇的提醒错误代码和业务无关,可以抽离为一个公共的方法,方便后面在其他地方调用,新建一个 utils/dialogs.dart 文件,将错误提示方法移到里面:

import 'package:flutter/material.dart';

class Dialogs {
  static void showInfo(BuildContext context, String info) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      content: Text(info),
    ));
  }
}

之前我们在列表是在 initialState 方法里主动刷新请求数据的,实际上 EasyRefresh 本身提供了一个属性firstRefresh来设置首次是否自动刷新,因此我们可以移除之前的主动刷新代码,将 firstRefresh 设置为 true 即可。

编辑页面实现

首先新增一个 dynamic_edit.dart 文件,里面有三个表单和一个按钮,分别对应的是标题、内容和图片链接地址(这里我们暂时不考虑图片上传)。表单利用的是我们之前封装的通用表单组件,可以参考之前的:Flutter 入门与实战(十):封装一个通用的文本输入框。这里在没有请求到数据的时候我们显示“加载中...”,若请求成功则显示实际的表单内容,构建界面的代码如下:

_getFormWidgets() {
  if (_formData == null)
    return Center(
      child: Text('加载中...'),
    );
  return Container(
    child: Column(
      children: [
        FormUtil.textField(
          'title',
          _formData['title']['value'] ?? '',
          controller: _formData['title']['controller'] ?? null,
          hintText: '请输入标题',
          prefixIcon: Icons.title,
          onChanged: _handleTextFieldChanged,
          onClear: _handleClear,
        ),
        FormUtil.textField(
          'content',
          _formData['content']['value'] ?? '',
          controller: _formData['content']['controller'] ?? null,
          hintText: '请输入内容',
          prefixIcon: Icons.content_paste,
          onChanged: _handleTextFieldChanged,
          onClear: _handleClear,
        ),
        FormUtil.textField(
          'imageUrl',
          _formData['imageUrl']['value'] ?? '',
          controller: _formData['imageUrl']['controller'] ?? null,
          hintText: '请输入图片链接',
          prefixIcon: Icons.image,
          onChanged: _handleTextFieldChanged,
          onClear: _handleClear,
        ),
        ButtonUtil.primaryTextButton('保存', () {
          _handleSubmit();
        }, context),
      ],
    ),
  );
}

在列表项的长按弹层中我们增加了一个编辑按钮,点击后跳转到编辑页面,具体参考源码即可。

获取详情数据

在编辑前,我们要通过 id 请求后台数据来填充表单,这里使用之前讲过的 get 请求,方法如下。若请求成功,返回状态码200时,构建表单的_formData数据,也就是表单所需要的数据,同时更新界面。如果请求失败则调用封装的信息提示方法,显示错误信息。

void _getDynamic(String id) async {
    try {
      var response = await DynamicService.get(id);
      if (response.statusCode == 200) {
        dynamicEntity = DynamicEntity.fromJson(response.data);
        setState(() {
          _formData = {
            'title': {
              'value': dynamicEntity.title,
              'controller': TextEditingController(text: dynamicEntity.title),
              'obsecure': false,
            },
            'content': {
              'value': dynamicEntity.content,
              'controller': TextEditingController(text: dynamicEntity.content),
              'obsecure': false,
            },
            'imageUrl': {
              'value': dynamicEntity.imageUrl,
              'controller': TextEditingController(text: dynamicEntity.imageUrl),
              'obsecure': false,
            },
          };
        });
      } else {
        Dialogs.showInfo(this.context, response.statusMessage);
      }
    } on DioError catch (e) {
      Dialogs.showInfo(this.context, e.message);
    } catch (e) {
      Dialogs.showInfo(this.context, e.toString());
    }
  }

提交更新数据

在提交数据前我们需要做校验,这里为了简单起见,只是保证数据不为空即可,后续我们可以校验工具来对各个字段进行准确的校验。校验通过后,从_fromData中提取实际要提交的表单数据。

_handleSubmit() async {
  if ((_formData['title']['value'] as String).trim() == '') {
    Dialogs.showInfo(this.context, '标题不能为空');
    return;
  }

  if ((_formData['content']['value'] as String).trim() == '') {
    Dialogs.showInfo(this.context, '内容不能为空');
    return;
  }

  if ((_formData['imageUrl']['value'] as String).trim() == '') {
    Dialogs.showInfo(this.context, '图片链接不能为空');
    return;
  }

  try {
    Map<String, String> newFormData = {};
    _formData.forEach((key, value) {
      newFormData[key] = value['value'];
    });
    var response = await DynamicService.update(dynamicEntity.id, newFormData);
    if (response.statusCode == 200) {
      Dialogs.showInfo(context, '保存成功');
    } else {
      Dialogs.showInfo(this.context, response.statusMessage);
    }
  } on DioError catch (e) {
    Dialogs.showInfo(this.context, e.message);
  } catch (e) {
    Dialogs.showInfo(this.context, e.toString());
  }
}

实际可以发现,我们的网络请求除了请求方法不同以外,其他代码几乎如出一辙,这也是后面的篇章需要统一封装的原因,要不太多重复代码了,万一哪天改起来会很痛苦。DynamicService.update接收要更新的数据的 id 和要更新的表单数据,实际就是简单调用了 Diopatch 方法。

static Future update(String id, Map<String, dynamic> data) async {
  var result = await Dio().patch(host + 'dynamics/' + id, data: data);

  return result;
}

运行效果

编辑完成后,我们重新刷新数据,可以看到内容和图片都发生了改变(如何保存成功后自动同步列表,我们讲完添加后再一起来解决)。

屏幕录制2021-07-05 下午9.59.35.gif

总结

本篇介绍了详情数据的获取,实体对象的部分修改来展示 Dio的 patch 请求。可以看到,Dio 提供的一系列 Restful 请求的方式基本相同,这样给我们统一封装留下了空间。下一篇我们介绍如何创建数据以及操作成功后如何同步更新后的数据到列表,网络相关代码源码地址为:https://gitee.com/island-coder/flutter-beginner/tree/master/network


欢迎关注个人公众号:岛上码农

相关文章
|
27天前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
106 4
|
28天前
|
缓存 监控 前端开发
优化 Flutter 应用启动速度的策略,涵盖理解启动过程、资源加载优化、减少初始化工作、界面布局优化、异步初始化、预加载关键数据、性能监控与分析等方面
本文探讨了优化 Flutter 应用启动速度的策略,涵盖理解启动过程、资源加载优化、减少初始化工作、界面布局优化、异步初始化、预加载关键数据、性能监控与分析等方面,并通过案例分析展示了具体措施和效果,强调了持续优化的重要性及未来优化方向。
54 10
|
2天前
|
XML JSON 前端开发
一文带你了解 Flutter dio封装
一文带你了解 Flutter dio封装
|
28天前
|
开发框架 前端开发 定位技术
Flutter框架中的插件市场及开源资源的利用方法。内容涵盖插件市场的扩展功能、时间节省与质量保证
本文深入探讨了Flutter框架中的插件市场及开源资源的利用方法。内容涵盖插件市场的扩展功能、时间节省与质量保证,常见插件市场的介绍,选择合适插件的策略,以及开源资源的利用价值与注意事项。通过案例分析和对社区影响的讨论,展示了这些资源如何促进开发效率和技术进步,并展望了未来的发展趋势。
36 11
|
27天前
|
传感器 前端开发 Android开发
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求。本文深入探讨了插件开发的基本概念、流程、集成方法、常见类型及开发实例,如相机插件的开发步骤,同时强调了版本兼容性、性能优化等注意事项,并展望了插件开发的未来趋势。
39 2
在 Flutter 中如何使用 ChangeNotifierProvider 实现数据共享?
在 Flutter 中如何使用 ChangeNotifierProvider 实现数据共享?
|
1月前
深入理解Flutter鸿蒙next版本 中的Widget继承:使用extends获取数据与父类约束
本文详细介绍了Flutter中如何通过继承其他Widget来创建自定义组件。首先解释了Widget继承的基本概念,包括StatelessWidget和StatefulWidget的区别。接着通过具体示例展示了如何继承StatelessWidget和StatefulWidget,并在子类中访问父类的build方法和状态。最后,结合多个自定义Widget展示了如何在实际应用中灵活使用继承和组合来构建复杂的UI。
76 8
|
1月前
|
存储 缓存 Dart
Flutter&鸿蒙next 封装 Dio 网络请求详解:登录身份验证与免登录缓存
本文详细介绍了如何在 Flutter 中使用 Dio 封装网络请求,实现用户登录身份验证及免登录缓存功能。首先在 `pubspec.yaml` 中添加 Dio 和 `shared_preferences` 依赖,然后创建 `NetworkService` 类封装 Dio 的功能,包括请求拦截、响应拦截、Token 存储和登录请求。最后,通过一个登录界面示例展示了如何在实际应用中使用 `NetworkService` 进行身份验证。希望本文能帮助你在 Flutter 中更好地处理网络请求和用户认证。
167 1
|
1月前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
113 1
|
1月前
|
JSON Dart 数据格式
<大厂实战场景> ~ flutter&鸿蒙next处理后端返回来的数据的转义问题
在 Flutter 应用开发中,处理后端返回的数据是常见任务,尤其涉及转义字符时。本文详细探讨了如何使用 Dart 的 `dart:convert` 库解析包含转义字符的 JSON 数据,并提供了示例代码和常见问题的解决方案,帮助开发者有效处理数据转义问题。
134 0