DOM转JSON的实现

简介: DOM转JSON的实现


前言


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

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


问题背景


640.png


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


解决思路


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


  • 获取供应日期,存进一个变量中。
  • 获取表头数据,存进一个数组中。
  • 获取表格内容,存进一个数组中。
  • 遍历表格内容,将表格中的数据与表头一一对应,存进一个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代码获取我们需要的数据


<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。

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


转换成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));


640.png


网友的实现思路


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

  • 沸点评论区网友:@boboka123的解决方案


640.png


  • 校友@_Dreams的解决方案


640.jpg


  • 群友@Cavey的解决方案


640.png


  • 群友@ssh的解决方案


640.png


  • 群友@聆听心底的浪潮、的解决方案


640.png


写在最后


  • 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊
  • 本文首发于掘金,未经许可禁止转载💌
相关文章
|
7月前
|
XML JSON 前端开发
dom4j - 使用详解与xml-json转换
dom4j - 使用详解与xml-json转换
168 1
|
存储 JSON JavaScript
|
存储 JSON 算法
Json字段选取器介绍和实现
Json字段选取器介绍和实现
220 0
Json字段选取器介绍和实现
|
存储 JSON 数据库
使用jackson的@JsonProperty()进行字段修改成自己想要的,并实现json字符串和list集合相互转换
使用jackson的@JsonProperty()进行字段修改成自己想要的,并实现json字符串和list集合相互转换
858 0
使用jackson的@JsonProperty()进行字段修改成自己想要的,并实现json字符串和list集合相互转换
|
JSON 缓存 搜索推荐
手写JAVA实现个性化业务的Excel转JSON,效率提高99.99%
由JSON数据的格式可以看出,每读取一个目录数据,都可以看成一个JSONObject,JSONObject有两个键值对,text代表目录的名字、children代表子目录。 一个父目录可以有多个子目录,所以children用的JSONArray去表示。
587 0
手写JAVA实现个性化业务的Excel转JSON,效率提高99.99%
|
JSON 监控 前端开发
(扩展)网站流量日志分析--数据可视化-- vue 版--复杂 json 具体实现 | 学习笔记
快速学习(扩展)网站流量日志分析--数据可视化-- vue 版--复杂 json 具体实现
(扩展)网站流量日志分析--数据可视化-- vue 版--复杂  json 具体实现 | 学习笔记
|
JSON 前端开发 Java
json 的实现 | 学习笔记
快速学习 json 的实现,介绍了 json 的实现系统机制, 以及在实际应用过程中如何使用。
json 的实现 | 学习笔记
|
JSON 前端开发 JavaScript
js处理json数据(合并键值对相同的数据,指定键值对相加或拼接)、前端实现
js处理json数据(合并键值对相同的数据,指定键值对相加或拼接)、前端实现
764 0
js处理json数据(合并键值对相同的数据,指定键值对相加或拼接)、前端实现
|
JSON NoSQL MongoDB
分布式服务器框架之Servers.Core库中实现MongoDB的ObjectId和Json转换
分布式服务器框架之Servers.Core库中实现MongoDB的ObjectId和Json转换
|
JSON 算法 数据安全/隐私保护
Python:使用PyJWT实现JSON Web Tokens加密解密
Python:使用PyJWT实现JSON Web Tokens加密解密
293 0