JavaScript/EJS开发中点击按钮时每行按钮重复增减的异常问题
问题原因
异常的核心是模板内层循环的逻辑写错了:
- 你在渲染每个商品行的操作列时,会完整遍历整个
homeProduct数组 - 遍历过程中每判断一次「当前homeProduct条目是否和当前商品匹配」,就直接渲染一个按钮,没有做「每行只渲染1个按钮」的控制
- 最终效果就是
homeProduct数组有多少个元素,每行就会渲染多少个按钮:点击AddToHomePage时会往homeProduct新增一条数据,数组长度+1,每行按钮就多1个;点击DeleteFromHomePage时会从homeProduct删除一条数据,数组长度-1,每行按钮就少1个,和你碰到的异常表现完全吻合。
修复方法
不要在内层循环里直接渲染按钮,先通过循环给当前商品打「是否已加入首页」的标记,等整个homeProduct数组遍历完,再根据标记结果只渲染1个对应按钮即可。
修复后的模板代码:
<% for (var i=0; i < loadPosts.length; i++) { %> <tr> <td><%= loadPosts[i].name %></td> <td><%= loadPosts[i].price %></td> <td><%= loadPosts[i].id %></td> <td> <% // 初始化标记:默认当前商品未加入首页 let isAddedToHome = false; for (var j = 0; j < homeProduct.length; j++) { if (homeProduct[j].ProductId === loadPosts[i].id) { isAddedToHome = true; break; // 找到匹配项直接终止循环,减少不必要的遍历 } } %> <% if (isAddedToHome) { %> <button class="btn btn-danger"> <a style="color: white; cursor: pointer; text-decoration: none;" href="/deleteFromHomePage/<%= loadPosts[i]._id %>"> DeleteFromHomePage </a> </button> <% } else { %> <button class="btn btn-primary"> <a style="color: white; cursor: pointer; text-decoration: none;" href="/addToHomePage/<%= loadPosts[i]._id %>"> AddToHomePage </a> </button> <% } %> </td> <td> <button class="btn btn-danger"> <a style="color: white; cursor: pointer; text-decoration: none;" href="/delete/<%= loadPosts[i]._id %>"> Delete </a> </button> </td> </tr> <% } %>
可选优化
- 可以直接在后端处理数据时,给
loadPosts的每个商品条目提前加上isAddedToHome的布尔字段,前端模板直接读取字段渲染即可,不用在模板里写双层循环,代码更简洁、渲染性能更好。 - 不建议在
<button>标签内部嵌套<a>标签,不符合HTML语义规范,可以直接给<a>标签加Bootstrap的按钮样式类实现同样效果,或者把跳转逻辑绑定到按钮的点击事件上。
内容的提问来源于stack exchange,提问作者Otoniel
相关产品推荐
相关产品推荐

