Node.js开发TODO列表时页面刷新后checkbox选中状态丢失如何解决
TODO列表复选框状态持久化解决方案
1. 调整后端数据结构与接口
你当前只存储了待办内容的字符串,需要将存储结构调整为对象,同时新增状态更新接口:
const express = require('express'); const app = express(); // 记得开启表单参数解析,否则无法读取post请求的body内容 app.use(express.urlencoded({ extended: true })); // 原字符串数组改为对象数组,每个元素包含待办内容和完成状态 const items = []; // 原新增待办接口调整存入格式 app.post("/", function(req, res){ let item = req.body.newItem; items.push({ content: item, completed: false // 新增大项默认未完成 }); res.redirect("/"); }); // 新增切换待办完成状态的接口 app.post("/toggleCompleted", function(req, res) { const itemIndex = req.body.index; if(items[itemIndex]) { items[itemIndex].completed = !items[itemIndex].completed; res.sendStatus(200); } else { res.sendStatus(400); } });
渲染页面时将完整的items对象数组传递给模板即可,比如res.render('你的模板名', { newListItems: items, listTitle: '你的列表标题' })
2. 修改前端模板与交互逻辑
修正循环生成重复id的问题,同时渲染时根据存储的状态控制复选框选中状态,新增状态同步交互:
<div class="box" > <% for (var i=0; i<newListItems.length; i++) { %> <div class="item"> <!-- 用索引标识当前待办,根据completed属性判断是否默认选中 --> <input type="checkbox" class="checkBox" data-index="<%= i %>" <%= newListItems[i].completed ? "checked" : "" %>> <!-- 可以直接在渲染时给已完成项加删除线样式 --> <p style="<%= newListItems[i].completed ? 'text-decoration: line-through; opacity: 0.7;' : '' %>"> <%= newListItems[i].content %> </p> </div> <% } %> <form action="/" method="post" class="item"> <input class="inputBox" type="text" name="newItem" placeholder="New item" autocomplete="off" required="required"> <button type="submit" name="list" value="<%= listTitle %>"> +</button> </form> </div> <script> // 监听所有复选框的选中事件,同步状态到后端 document.querySelectorAll('.checkBox').forEach(check => { check.addEventListener('change', function() { const index = this.dataset.index; // 发送请求更新后端状态 fetch('/toggleCompleted', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `index=${index}` }) // 本地实时更新样式,无需等待页面刷新 const textNode = this.nextElementSibling; textNode.style.textDecoration = this.checked ? 'line-through' : 'none'; textNode.style.opacity = this.checked ? '0.7' : '1'; }) }) </script>
内容的提问来源于stack exchange,提问作者greatTriangle
相关产品推荐
相关产品推荐

