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的解決方案
  • 羣友@聆聽心底的浪潮、的解決方案

寫在最後

  • 文中若有錯誤,歡迎在評論區指正,若是這篇文章幫到了你,歡迎點贊和關注😊
  • 本文首發於掘金,未經許可禁止轉載💌
相關文章
相關標籤/搜索