DOM转JSON的实现

前言

昨天组员在业务开发中遇到了一个菜品领取登记表修改菜品后,如何将修改后的数据以json的形式发给后端的问题,我在解决这个问题时,发现这个问题蛮有意思,因而就将这个问题发到了沸点和群里,看了你们的解决思路后,学到了很多知识。html

接下来就以这个问题为背景,讲解这个功能如何实现,欢迎各位感兴趣的开发者阅读本文。web

问题背景

如上图所示,在菜品领取登记表里,用户能够里输入各个菜品的数量,输入完成后点保存生成json数据,调接口将供应日期放进生成的json数据一并发给后端,后端拿到json数据后修改数据库中的数据。ajax

解决思路

观察菜品领取登记表后,咱们发现表中姓名为固定数据,其余字段都是后端返的动态数据,表格的内容也是动态的,每行数据描述了其姓名所对应的菜品以及菜品数量,咱们根据这些已知条件整理下思路,将这些数据用js从dom中提取出来。数据库

  • 获取供应日期,存进一个变量中。
  • 获取表头数据,存进一个数组中。
  • 获取表格内容,存进一个数组中。
  • 遍历表格内容,将表格中的数据与表头一一对应,存进一个JSON数组中。
  • 将供应日期和表格内容的json数组放进一个对象中,调接口将数据发送给后端。

解决方案

对页面进行分析后,咱们获得了解决思路,接下来咱们将上述思路转换为代码:json

  • 菜品领取登记表的DOM结构以下:
<!--查询列表-->
<table class="search">  <tbody><tr>  <td>  姓名:  <input type="text" name="xm">&nbsp;  供应日期:  <input type="text" id="gyrq" name="gyrq" onclick="wd.edit.datePicker({dateFmt:'yyyy-MM-dd'})" value="2020-04-30" id="gyrq">&nbsp;  <button type="button" class="btn" onclick="document.getElementById('form').submit();">查询</button>  </td>  <td style="text-align: right;">  <button type="button" class="btn" id="dc">导出</button>  <button type="button" class="btn" id="dy">打印</button>  </td>  </tr>  </tbody> </table>  <div class="list-div" id="tb1">  <table class="list">  <thead>  <tr>  <th style="text-align: center;">姓名</th>   <th style="text-align: center;">  牛肉03  </th>   <th style="text-align: center;">  鸡肉002  </th>   </tr>  </thead>  <tbody wdoddclass="list-odd" wdevenclass="list-even" wdmouseoverclass="list-mouseover" id="wdTbody0">   <tr class=" list-odd">  <td style="text-align: center;">  青秀山  </td>   <td style="text-align: center;">  <input type="text" style="width: 100px;" name="mc" value="0">  </td>   <td style="text-align: center;">  <input type="text" style="width: 100px;" name="mc" value="15">  </td>   </tr>   <tr class=" list-even">  <td style="text-align: center;">  a  </td>   <td style="text-align: center;">  <input type="text" style="width: 100px;" name="mc" value="0">  </td>   <td style="text-align: center;">  <input type="text" style="width: 100px;" name="mc" value="0">  </td>   </tr>   </tbody>  </table> </div> 复制代码
  • 根据dom结构编写js代码获取咱们须要的数据
// 表格对象
let tableObj = {}; // 供应日期 tableObj.gyrq = $("#gyrq").val(); // 获取全部的标题 const titleArr = $("#tb1 table thead tr"); // 获取全部的内容 const contentArr = $("#tb1 table tbody");  // 列表数据 let data = []; // 遍历全部的内容 for(let i = 0; i < contentArr.children().length; i++){  // 每个内容对象  let obj = {};  // 遍历全部的标题  for(let j = 0; j < titleArr.children().length; j++){  // 获取每一个标题  let key = (titleArr.children().eq(j).html()).replace(/\s/g, "");  if(j ===0){  // 姓名的dom结构是html  obj[`${key}`] = (contentArr.children().eq(i).children().eq(j).html()).replace(/\s/g, "");  }else{  // 其余字段的dom结构是input  obj[`${key}`] = (contentArr.children().eq(i).children().eq(j).children().val()).replace(/\s/g, "");  }  }  // 将每一个对象放进数组里  data.push(obj); } tableObj.data = data; 复制代码
  • 调用接口将获取到的json数据发给后台
$.ajax({
 url:"",  data:tableObj,  type:"POST",  success:(res)=>{   } }) 复制代码

JSON二次处理

上述代码将dom中的数据转成json后,后端说这不是他要的格式,这种数据他没法解析,而后发了json格式给我,让我按照他的格式转一下。后端

我跟后端说:你直接在你那边转成你要的格式就行了。 后端:你直接在页面转,我后端转的话会形成不必的资源浪费。 我:行吧,那我转吧。数组

  • 后端给个人json格式:
{
 time:"xxxx-xx-xx",  data:[  {  name:"xx",  title:"",  num:""  }  ] } 复制代码
  • 我解析的json格式
{
 "time":"2020-04-30",  "data":[  {"姓名": "青秀山", "牛肉03": "0", "鸡肉002": "15"},  {"姓名": "a", "牛肉03": "0", "鸡肉002": "0"}  ] }  复制代码

难点分析

后端须要的数据为把每一个人的数据拆分出来。并发

例如,名字为青秀山客户,他点了牛肉03,数量为0,鸡肉002数量为15。dom

名字为a的客户,他点了牛肉03数量为0,鸡肉002数量为0。ssh

转换成json后的代码为:

{
 "time": "2020-04-30",  "data": [  {  "name": "青秀山",  "title": "牛肉03",  "num": "0"  },  {  "name": "青秀山",  "title": "鸡肉002",  "num": "15"  },  {  "name": "a",  "title": "牛肉03",  "num": "0"  },  {  "name": "a",  "title": "鸡肉002",  "num": "0"  }  ] } 复制代码

观察咱们生成的json数据和后端须要的json数据后,发现了以下规律:

  • 咱们生成的json数据中,姓名是已知字段,其余字段是动态未知的。
  • 后端须要的json数据中,data中json对象的个数,是根据咱们生成的json数据中的动态字段数量决定的。

代码实现

知道规律后,咱们就能够用js实现这个解析器了。

/**  * json解析器  * @param jsonObj  * @returns {{}}  * @constructor  */ const JsonParse = function (jsonObj= {}) {  let resultObj = {};  // time是固定值,因此可直接取出来  resultObj.time = jsonObj.time;  resultObj.data = [];  for (let i = 0; i < jsonObj.data.length; i++){  // 获取数组里的每一项对象  const dataObj = jsonObj.data[i];  // 转换后的每一项json对象  let resultDataObj = {};  // 转换后的对象姓名,由于姓名为固定值,遍历对象时须要加上。  let resultDataObjName = "";  // 遍历数组里的每一项对象  for (let key in dataObj){  // 若是dataObj对象里的key不存在则终止本次循环  if(!dataObj.hasOwnProperty(key)) continue;  // 姓名为固定条件  if(key === "姓名"){  // 记录名字  resultDataObjName = dataObj["姓名"];  }else{  // 动态条件,此时key为除姓名之外的值,获取当前key的名字和数量  resultDataObj.name = resultDataObjName;  resultDataObj.title = key;  resultDataObj.num = dataObj[key];  // name、title、num为已知值,将当前对象放进结果对象的data里  resultObj.data.push(resultDataObj);  // 清空当前对象,继续下一个key的遍历  resultDataObj = {};  }  }  }  return resultObj; } 复制代码

对上述代码进行运行测试

// 测试数据
const dataObj ={  "time":"2020-04-30",  "data":[  {"姓名": "青秀山", "牛肉": "0", "鸡肉": "15"},  {"姓名": "a", "牛肉": "0", "鸡肉": "0","鸡蛋":"12"},  {"姓名": "test", "猪肉": "0", "鸭肉": "0"}  ] }  console.log(JsonParse(dataObj)); 复制代码

网友的实现思路

将咱们生成的json转为后端所须要的格式,这是一个有意思的问题。因而我将这个问题发到了群里和掘金沸点,看看你们的解题思路,接下来我就把你们的实现代码贴出来。

  • 沸点评论区网友:@boboka123的解决方案
  • 校友@_Dreams的解决方案
  • 群友@Cavey的解决方案
  • 群友@ssh的解决方案
  • 群友@聆听心底的浪潮、的解决方案

写在最后

  • 文中若有错误,欢迎在评论区指正,若是这篇文章帮到了你,欢迎点赞和关注😊
  • 本文首发于掘金,未经许可禁止转载💌
相关文章
相关标签/搜索