Express+EJS+MongoDB待办列表需刷新才显示更改的问题
解决方案
一、修复现有代码的异步操作问题(保持页面跳转模式)
你的代码中多处未正确等待MongoDB异步操作完成就执行了res.redirect,导致数据库更新还未完成,页面就已经刷新,因此看不到最新数据。需要将所有异步操作的回调改为正确的Promise处理:
修改后的关键代码片段:
- 首页默认数据插入:
app.get('/' , (req, res) =>{ const date = Date.getdate(); Item.find({}) .then((founditems) => { if(founditems.length === 0){ Item.insertMany(defaultItems) // 等待插入完成后再重定向 .then(() => res.redirect('/')) .catch(err => console.log("插入默认数据出错: " + err)) } else{ const homelist = "True"; res.render('list', {list_title: date, items: founditems, homelist:homelist}) } }) .catch(err =>console.log(err)) })
- 添加新项接口:
app.post('/', async (req, res)=>{ const item = req.body.user_item; const customListName = req.body.list; const homelist = req.body.homelist; const newItem = new Item({ name: item, }) if(item !== "" && homelist === "False"){ List.findOne({name: customListName}) .then((founditem)=>{ founditem.items.push(newItem) // 等待保存完成后重定向 founditem.save() .then(() => res.redirect("/"+customListName)) .catch(err => console.log("保存自定义列表出错: ", err)) }) .catch(err => console.log("未找到自定义列表: ", err)) } else if(item !== "" && homelist === "True"){ // 等待保存完成后重定向 newItem.save() .then(() => res.redirect('/')) .catch(err => console.log("保存主列表项出错: ", err)) } })
- 删除项接口:
app.post("/delete", (req, res)=>{ const _id = req.body.checkbox; const homelist = req.body.homelist; if(homelist === "False"){ const customListName = req.body.Deletelist; List.findOneAndUpdate( { name: customListName }, { $pull: { items: { _id: _id } } }, { new: true }, ) // 等待更新完成后重定向 .then(() => res.redirect('/'+customListName)) .catch(err => console.log("删除自定义列表项出错: ", err)) } else{ Item.findByIdAndRemove(_id) // 等待删除完成后重定向 .then(() => res.redirect('/')) .catch(err => console.log("删除主列表项出错: ", err)) } })
- 自定义列表创建:
app.get("/:customList" , (req, res)=>{ const customList = _.capitalize(req.params.customList); List.findOne({name: customList}) .then((data) =>{ if(data === null){ const initialItems = new List({ name: customList, items : defaultItems, }) // 等待保存完成后重定向 initialItems.save() .then(() => res.redirect("/"+customList)) .catch(err => console.log("创建自定义列表出错: ", err)) } else{ const homelist = "False"; res.render('list', {list_title: data.name, items: data.items, homelist: homelist}) } }) .catch((err) => console.log(err)) })
二、实现无刷新更新(推荐,提升用户体验)
如果不想依赖页面跳转,可改用AJAX异步请求,前端动态更新DOM:
1. 前端EJS页面修改(list.ejs)
在页面末尾添加脚本,拦截表单提交和删除操作,改用异步请求:
<script> // 处理添加项 document.querySelector('form[action="/"]').addEventListener('submit', async (e) => { e.preventDefault(); const formData = new FormData(e.target); const itemName = formData.get('user_item'); if (!itemName.trim()) return; try { const res = await fetch('/', { method: 'POST', body: formData }); const result = await res.json(); // 动态添加新项到列表 const list = document.querySelector('ul'); const newLi = document.createElement('li'); newLi.innerHTML = ` <input type="checkbox" name="checkbox" value="${result.item._id}" onchange="deleteItem(this)"> <span>${result.item.name}</span> `; list.appendChild(newLi); e.target.reset(); } catch (err) { alert('添加失败,请重试'); console.error(err); } }); // 处理删除项 async function deleteItem(checkbox) { const itemId = checkbox.value; const homelist = "<%= homelist %>"; const listName = "<%= list_title %>"; const formData = new FormData(); formData.append('checkbox', itemId); formData.append('homelist', homelist); if (homelist === "False") { formData.append('Deletelist', listName); } try { await fetch('/delete', { method: 'POST', body: formData }); // 动态移除DOM元素 checkbox.parentElement.remove(); } catch (err) { alert('删除失败,请重试'); console.error(err); } } </script>
2. 后端接口修改
将重定向改为返回JSON响应:
// 修改添加项接口 app.post('/', async (req, res)=>{ const item = req.body.user_item; const customListName = req.body.list; const homelist = req.body.homelist; const newItem = new Item({ name: item, }) if(item !== "" && homelist === "False"){ const founditem = await List.findOne({name: customListName}); founditem.items.push(newItem); await founditem.save(); res.json({success: true, item: newItem}); } else if(item !== "" && homelist === "True"){ await newItem.save(); res.json({success: true, item: newItem}); } else { res.json({success: false, message: "项不能为空"}); } }) // 修改删除项接口 app.post("/delete", async (req, res)=>{ const _id = req.body.checkbox; const homelist = req.body.homelist; if(homelist === "False"){ const customListName = req.body.Deletelist; await List.findOneAndUpdate( { name: customListName }, { $pull: { items: { _id: _id } } }, { new: true }, ); res.json({success: true}); } else{ await Item.findByIdAndRemove(_id); res.json({success: true}); } })
内容的提问来源于stack exchange,提问作者Ayush Singh
相关产品推荐
相关产品推荐

