【问题标题】:jQuery reorder and structure Ajax datajQuery 重新排序和结构化 Ajax 数据
【发布时间】:2021-12-29 20:44:47
【问题描述】:

我有两个维度的数据,一是购买本身,二是推荐参考。订单由 PDO 生成并取自 MySQL 数据库:

<div rfrnc="joe" id="1" class="order"><div>1 Laptop $220</div><div class="time">10.25</div></div>
<div rfrnc="bill" id="2" class="order"><div>1 Phone $520</div><div class="time">10.10</div></div>
<div rfrnc="joe" id="3" class="order"><div>1 Headset $220</div><div class="time">9.20</div></div>
<div rfrnc="bill" id="4" class="order"><div>1 Laptop $220</div><div class="time">9.02</div></div>
<div rfrnc="joe" id="5" class="order"><div>1 Laptop $220</div><div class="time">11.02</div></div>

使用ajax,上面的html会被直接解析成我网站上的实时提要,通过orderid或购买日期,通过3种相同函数的api调用(取决于参数来识别每个操作)进行排序:

  1. 初始加载(5 个条目)和加载更多按钮(每次 +5)

    $(".wrapper").append(html);  
    
  2. websocket ping 仅触发相同的 api 调用和从 mysql 检索(仅返回一个订单 - 实时提要)

    $(".wrapper").prepend(html); 
    
  3. 当订单已经在实时提要中但状态发生变化时,websocket 会更新

    $("#" + orderid).replaceWith(html);
    

我遇到的问题是如何将 html div 转换为按引用进行显示和分组,如下所示。

<div rfrnc="joe">
<div id="5" class="order">...</div>
<div id="3" class="order">...</div>
<div id="1" class="order">...</div>
</div>
<div rfrnc="bill">
<div id="4" class="order">...</div>
<div id="2" class="order">...</div>
</div>

我尝试了各种各样的事情,比如重写源 php html,重写 sql 查询以使用 group_concat 以及使用 wrapAll 和类似的 jquery 东西来修改已经从 ajax 调用返回但没有运气的 html。单击任一订单以更改其状态时,还有进一步的 ajax 操作。对于具有相同参考的所有订单,我需要在组级别上相同。对不起,如果我没有解释清楚。

【问题讨论】:

  • 此时我什至愿意切换到 JSON 数据而不是解析 html 并将所有循环和 html 移动到 jQuery。

标签: javascript php jquery mysql ajax


【解决方案1】:

solution 循环现有条目并按data-rfrnc 属性对它们进行分组:

const people = {};

const html = `<div data-rfrnc="joe" id="1" class="order"><div>1 Laptop $220</div><div class="time">10.25</div></div>
<div data-rfrnc="bill" id="2" class="order"><div>1 Phone $520</div><div class="time">10.10</div></div>
<div data-rfrnc="joe" id="3" class="order"><div>1 Headset $220</div><div class="time">9.20</div></div>
<div data-rfrnc="bill" id="4" class="order"><div>1 Laptop $220</div><div class="time">9.02</div></div>
<div data-rfrnc="joe" id="5" class="order"><div>1 Laptop $220</div><div class="time">11.02</div></div>
`
const domParser = new DOMParser();
const doc = domParser.parseFromString(html, "text/html")


Array.from(doc.querySelectorAll('body > div')).forEach(div => {
  const person = div.getAttribute('data-rfrnc');
  if (!people[person]) {
     people[person] = [];
  }
  people[person].push(div)
})


const docFrag = document.createDocumentFragment();
for(let [person, elements] of Object.entries(people)) {
  const personElement = document.createElement('div');
  personElement.setAttribute('data-rfrnc', person);
  elements
    .sort((a,b) => a.getAttribute('id') < b.getAttribute('id'))
    .forEach(element => personElement.appendChild(element));
  docFrag.appendChild(personElement);
}

document.body.appendChild(docFrag)

【讨论】:

  • 非常感谢,我喜欢它动态创建组 div 元素的事实。我认为它在一定程度上可以工作,但是是否可以使用 jQuery 来操作和排序 ajax 中的 html,然后再将其附加到 DOM?它只需要检查success(html) 中的div,然后决定是否将其附加到现有的组元素或添加新的组元素(以防它不存在或太旧)。
  • 更好的解决方案是返回 JSON 并从 JSON 创建 DOM。如果您要在将 HTML 添加到 DOM 之前对其进行操作,则从服务器返回 HTML 是次优的。我认为使用像 Vue、React 或 Preact 这样的响应式前端库对你来说很有意义。这些是数据驱动的库,可以根据数据的变化轻松更改渲染 DOM 的方式。
  • 我编辑了解决方案以使用 HTML 字符串而不是 DOM。
【解决方案2】:

我完全支持 @firstlast 在他的评论中发送 JSON 数据并在前端处理它会是更好的解决方案。

以防万一有人感兴趣,这里是另一种将接收到的 html 字符串转换回 JavaScript 数组数组的方法:

const html=`<div rfrnc="joe" id="1" class="order"><div>1 Laptop $220</div><div class="time">10.25</div></div>
<div rfrnc="bill" id="2" class="order"><div>1 Phone $520</div><div class="time">10.10</div></div>
<div rfrnc="joe" id="3" class="order"><div>1 Headset $220</div><div class="time">9.20</div></div>
<div rfrnc="bill" id="4" class="order"><div>1 Laptop $220</div><div class="time">9.02</div></div>
<div rfrnc="joe" id="5" class="order"><div>1 Laptop $220</div><div class="time">11.02</div></div>`;

const dom=document.createElement("div");
dom.innerHTML=html
  
const data=[...dom.children].map(d=>[d.id,d.getAttribute("rfrnc")].concat([...d.children].flatMap(c=>c.textContent.split(" ")))
);

// show the result:
console.log(["id","rfrnc","qty","descr","price","time"]);
console.log(data);

【讨论】:

  • 从服务器接收 HTML 时,我肯定会考虑使用 innerHTML 的后果:stackoverflow.com/questions/37249170/…
  • @firstlast,感谢分享将new DOMParser()innerHHTML 进行比较的链接。在这个特定用例中使用innerHTML 的具体危险在哪里?不会以任何可以想象的方式触发任何脚本。因此,我无法想象这里会发生任何“坏”的事情。肯定总是值得关注可能的漏洞,但我也不相信害怕甚至不存在的东西。
  • innerHTML 将接受任何内容并且永远不会产生错误。当呈现格式错误或无效的 HTML 时,它简直是不可预测的。在服务器上生成 HTML 字符串通常容易出错。 DOMParse 至少让您有机会捕获格式错误的 HTML 错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多