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


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

相关文章
在 Flutter 中如何使用 ChangeNotifierProvider 实现数据共享?
在 Flutter 中如何使用 ChangeNotifierProvider 实现数据共享?
|
5月前
|
移动开发 JavaScript 前端开发
【Uniapp 专栏】Uniapp 与 Flutter 的功能特点对比
【5月更文挑战第15天】Uniapp 和 Flutter 是跨平台开发的热门框架。Uniapp 以其强大的跨平台兼容性和基于 Vue.js 的易学性著称,适合快速开发适用于 iOS、Android 和 H5 的应用。其丰富的组件生态简化了功能集成。然而,在复杂场景下,性能可能不及原生。Flutter 则以其全新渲染引擎实现流畅界面和高度自定义,性能接近原生,但学习成本较高,需处理特定平台适配。适用于高要求的项目。两者各有优势,选择应考虑项目需求、技术储备和开发周期。
692 1
【Uniapp 专栏】Uniapp 与 Flutter 的功能特点对比
|
2月前
|
前端开发
Flutter快速实现自定义折线图,支持数据改变过渡动画
Flutter快速实现自定义折线图,支持数据改变过渡动画
46 4
Flutter快速实现自定义折线图,支持数据改变过渡动画
|
3月前
|
JSON Dart API
Flutter dio http 封装指南说明
本文介绍了如何实现一个通用、可重构的 Dio 基础类,包括单例访问、日志记录、常见操作封装以及请求、输出、报错拦截等功能。
Flutter dio http 封装指南说明
|
2月前
|
开发者 监控 开发工具
如何将JSF应用送上云端?揭秘在Google Cloud Platform上部署JSF应用的神秘步骤
【8月更文挑战第31天】本文详细介绍如何在Google Cloud Platform (GCP) 上部署JavaServer Faces (JSF) 应用。首先,确保已准备好JSF应用并通过Maven构建WAR包。接着,使用Google Cloud SDK登录并配置GCP环境。然后,创建`app.yaml`文件以配置Google App Engine,并使用`gcloud app deploy`命令完成部署。最后,通过`gcloud app browse`访问应用,并利用GCP的监控和日志服务进行管理和故障排查。整个过程简单高效,帮助开发者轻松部署和管理JSF应用。
41 0
|
2月前
|
开发者 容器 Java
Azure云之旅:JSF应用的神秘部署指南,揭开云原生的新篇章!
【8月更文挑战第31天】本文探讨了如何在Azure上部署JavaServer Faces (JSF) 应用,充分发挥其界面构建能力和云平台优势,实现高效安全的Web应用。Azure提供的多种服务如App Service、Kubernetes Service (AKS) 和DevOps简化了部署流程,并支持应用全生命周期管理。文章详细介绍了使用Azure Spring Cloud和App Service部署JSF应用的具体步骤,帮助开发者更好地利用Azure的强大功能。无论是在微服务架构下还是传统环境中,Azure都能为JSF应用提供全面支持,助力开发者拓展技术视野与实践机会。
13 0
|
2月前
|
开发框架 API 开发者
Flutter表单控件深度解析:从基本构建到高级自定义,全方位打造既美观又实用的移动端数据输入体验,让应用交互更上一层楼
【8月更文挑战第31天】在构建美观且功能强大的移动应用时,表单是不可或缺的部分。Flutter 作为热门的跨平台开发框架,提供了丰富的表单控件和 API,使开发者能轻松创建高质量表单。本文通过问题解答形式,深入解读 Flutter 表单控件,并通过具体示例代码展示如何构建优秀的移动应用表单。涵盖创建基本表单、处理表单提交、自定义控件样式、焦点管理和异步验证等内容,适合各水平开发者学习和参考。
31 0
|
2月前
|
存储 缓存 安全
Flutter Dio进阶:使用Flutter Dio拦截器实现高效的API请求管理和身份验证刷新
Flutter Dio进阶:使用Flutter Dio拦截器实现高效的API请求管理和身份验证刷新
83 0
|
4月前
|
Dart 监控 开发者
详细介绍Flutter Profiler的功能、使用方法以及如何利用它来提升应用的性能
【6月更文挑战第11天】Flutter Profiler是用于优化Flutter应用的关键工具,提供CPU、GPU、内存和网络分析。它帮助开发者监控运行时性能,识别瓶颈,如CPU过度使用、渲染问题、内存泄漏和网络效率低。通过选择分析类型、开始分析、查看结果,开发者可进行针对性优化。最佳实践包括定期分析、结合实际场景、关注关键指标及结合其他工具。有效利用Profiler能提升应用性能和用户体验。
127 2
|
4月前
|
开发框架 开发者 UED
Flutter作为一款跨平台的移动应用开发框架,自然也提供了丰富的工具和功能来支持可访问性和无障碍设计
【6月更文挑战第11天】Flutter是一款注重可访问性设计的跨平台移动应用开发框架,提供语义化组件、文本缩放、对比度调整、动态内容更新通知和键盘导航等功能,支持无障碍体验。开发者应结合简化操作、清晰反馈、多输入方式支持及测试优化等原则,以创建包容性更强的应用,满足不同用户需求,体现社会责任。
49 1
下一篇
无影云桌面