You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express+EJS+MongoDB待办列表需刷新才显示更改的问题

解决方案

一、修复现有代码的异步操作问题(保持页面跳转模式)

你的代码中多处未正确等待MongoDB异步操作完成就执行了res.redirect,导致数据库更新还未完成,页面就已经刷新,因此看不到最新数据。需要将所有异步操作的回调改为正确的Promise处理:

修改后的关键代码片段:

  1. 首页默认数据插入:
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))
})
  1. 添加新项接口:
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))
 }
})
  1. 删除项接口:
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))
    }
})
  1. 自定义列表创建:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 09:55:03