NodeJS+Express+EJS+MongoDB嵌套列表新增项需刷新才显示求助
嵌套列表添加项后未即时显示的问题修复
问题背景
用NodeJS、Express、EJS和MongoDB开发嵌套列表功能,一级列表创建正常,但二级列表添加新项后,必须刷新页面或再次执行添加操作(添加操作会自动刷新页面)才能看到新项。
问题分析
核心问题出在MongoDB异步操作的处理逻辑上:
- POST路由中,
foundList.save()是异步方法,但你直接在调用save后就执行res.redirect,此时数据库可能还未完成写入,导致跳转后的GET请求读取到的仍是旧数据。 - GET路由中多余的
foundList.save()完全没必要,查询到数据后直接渲染即可,额外的save操作会引发不必要的数据库交互。
修复方案
1. 正确处理POST路由的异步保存
将foundList.save()改为带回调的形式,确保数据库写入完成后再跳转:
.post(function (req, res) { const customListID = req.params.customListID; const customListName = req.params.customListName; const itemName = req.body.newItem; const item = new Item({ name: itemName }); Country.findOne({ _id: customListID }, function (err, foundList) { if (err) { console.log(err); return res.redirect("/BucketList/" + customListID); } foundList.items.push(item); // 用回调确保保存完成后再跳转 foundList.save(function(err) { if (!err) { res.redirect("/BucketList/" + customListID); } else { console.log(err); res.redirect("/BucketList/" + customListID); } }); }); })
更推荐用async/await让代码逻辑更清晰:
.post(async function (req, res) { try { const customListID = req.params.customListID; const itemName = req.body.newItem; const item = new Item({ name: itemName }); const foundList = await Country.findOne({ _id: customListID }); foundList.items.push(item); await foundList.save(); res.redirect("/BucketList/" + customListID); } catch (err) { console.log(err); res.redirect("/BucketList/" + customListID); } })
2. 移除GET路由中多余的save操作
GET路由仅需查询数据并渲染,不需要额外保存:
.get(function (req, res) { previousRoute = "/BucketList"; if (req.isAuthenticated()) { loggedIn = true; const customListID = req.params.customListID; const customListName = req.params.customListName; Country.findOne({ _id: customListID }, function (err, foundList) { if (!err) { if (!foundList) { res.redirect("/BucketList") } else { // 移除多余的foundList.save() res.render("list", { customListID: customListID, customListName: customListName, customListCode: foundList.code, newListItems: foundList.items }); } } else { console.log(err); res.redirect("/BucketList"); } }) } else { loggedIn = false; res.redirect("/login"); } })
3. 优化视图列表结构(可选)
当前EJS循环中每个列表项都会生成独立的<ul>标签,样式上可能不符合预期,建议将<ul>移至循环外部:
<form class="d-flex justify-content-center align-items-center mb-4" action="/BucketList/<%=customListID%>" method="post"> <!-- 表单内容保持不变 --> </form> <!-- 将ul标签移至循环外 --> <ul class="list-group mb-0"> <% newListItems.forEach(function(item) { %> <li class="list-group-item d-flex justify-content-between align-items-center border-start-0 border-top-0 border-end-0 border-bottom rounded-0 mb-2"> <!-- li内容保持不变 --> </li> <% }) %> </ul>
内容的提问来源于stack exchange,提问作者Guy283
相关产品推荐
相关产品推荐

