我正在做一个待办事项列表项目。完成后,它在本地主机上运行良好,但当我部署它时,它的行为有所不同。
当我访问网站并给他们一个任务时,它会列出该任务,然后当我输入另一个任务时,它会突然替换旧任务,然后我又输入一个任务,这次它列出了前一个任务下方的任务。
这种情况发生在生产时,而不是在我的本地服务器上。
回购链接:https://github.com/GunjanKMishra/ToDoList
部署链接:https://listyourtodo.cycling.app
代码:
ejs 文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>To-Do List</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<nav>
<a href="/"><img src="calendar.png"> today</a>
<a href="/work"><img src="work.png"> work</a>
</nav>
</header>
<div class="box">
<h1>
<%= day %>, <%= date %>
<%= month %>
<%= year %>
</h1>
</div>
<% if (locals.task) { %>
<% for( let i=0; i < task.length; i++ ) { %>
<div class="card">
<input type="checkbox" name="taskCheckBox" class="checkbox check" id="check<%= i %>">
<p id="text<%= i %>">
<%= task[i] %>
</p>
</div>
<% } %>
<% } %>
<div class="task">
<form action="/" method="post">
<input type="text" name="taskItem" class="taskItem" autocomplete="off" required>
<input type="submit" value="+" class="btn">
</form>
</div>
<footer>
Copyright © 2023
</footer>
<!-- checkbox click strike through feature -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script>
$("[class^='check']").change(function () {
const checkbox = $(this);
const text = checkbox.siblings("p")
if (checkbox.prop("checked")) {
text.css({ "text-decoration": "line-through" });;
}
else {
text.css({ "text-decoration": "none" });;
}
});
</script>
</body>
</html>
index.js 文件
import bodyParser from "body-parser";
import expres from "express";
const app = expres();
const port = 3000;
app.use(expres.static("public"));
app.use(bodyParser.urlencoded({extended:true}));
const day = new Date().getDay();
const month = new Date().getMonth();
const date = new Date().getDate();
const year = new Date().getFullYear();
const tasks = {
today: [],
work: []
};
const dayA =['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
const monthA =['January','February','March','April','May','June','July','August','September','October','November','December'];
app.get("/",(req,res)=>{
res.render("./index.ejs",{
day:dayA[day],
month:monthA[month],
date: date,
year: year,
task: tasks.today,
});
});
app.get("/work",(req,res)=>{
res.render("./work.ejs",{task: tasks.work,});
});
app.post("/",(req,res)=>{
tasks.today.push(req.body['taskItem']);
res.render("./index.ejs",{
day:dayA[day],
month:monthA[month],
date: date,
year: year,
task: tasks.today,
});
});
app.post("/work",(req,res)=>{
tasks.work.push(req.body['taskItem']);
res.render("./work.ejs",{
task: tasks.work,
});
});
app.listen(port,()=>{console.log(`server has been sarted at port ${port}!`);});
它实际上应该列出所有任务。 但它并没有完美地列出任务。
分析: 待办事项列表应用程序的问题是任务未正确保留。添加新任务后,它会出现在主页上,但之前的任务会消失。此外,当导航到“/work”页面时,会列出所有任务,但添加新任务时会替换旧任务。
问题的出现是因为服务器的状态会随着每个新请求而重新初始化。这会导致任务数组在渲染页面之前重置为空,从而导致之前的任务丢失。
解决方案: 为了解决这个问题并确保任务正确持久化,我们需要实现更持久的数据存储方法。使用 MongoDB 这样的数据库将有助于永久存储任务。通过这样做,即使服务器重新启动或多个用户与应用程序交互,任务也将被保留。
下面是更新后的index.js文件,它集成了MongoDB作为存储任务的数据库:
import bodyParser from "body-parser";
import express from "express";
import mongoose from "mongoose";
const app = express();
const port = 3000;
app.use(express.static("public"));
app.use(bodyParser.urlencoded({ extended: true }));
// Connect to MongoDB (Make sure to have MongoDB server running)
mongoose.connect("mongodb://localhost:27017/todo_db", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
// Create a schema for the task model
const taskSchema = new mongoose.Schema({
name: String,
});
// Create mongoose model for tasks
const Task = mongoose.model("Task", taskSchema);
const dayA = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
const monthA = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
app.get("/", async (req, res) => {
try {
const tasks = await Task.find({});
res.render("./index.ejs", {
day: dayA[new Date().getDay()],
month: monthA[new Date().getMonth()],
date: new Date().getDate(),
year: new Date().getFullYear(),
task: tasks.map(task => task.name),
});
} catch (error) {
console.error("Error fetching tasks:", error);
res.status(500).send("Error fetching tasks");
}
});
app.get("/work", async (req, res) => {
try {
const tasks = await Task.find({});
res.render("./work.ejs", {
task: tasks.map(task => task.name),
});
} catch (error) {
console.error("Error fetching tasks:", error);
res.status(500).send("Error fetching tasks");
}
});
app.post("/", async (req, res) => {
try {
const newTask = new Task({
name: req.body['taskItem'],
});
await newTask.save();
res.redirect("/");
} catch (error) {
console.error("Error saving task:", error);
res.status(500).send("Error saving task");
}
});
app.post("/work", async (req, res) => {
try {
const newTask = new Task({
name: req.body['taskItem'],
});
await newTask.save();
res.redirect("/work");
} catch (error) {
console.error("Error saving task:", error);
res.status(500).send("Error saving task");
}
});
app.listen(port, () => {
console.log(`Server has been started at port ${port}!`);
});
通过使用MongoDB,您的任务将保存在数据库中,服务器将正确保留任务的状态。任务现在将以列表形式显示在网页上,新任务将不再替换旧任务。
在运行代码之前,请确保您已在本地计算机上安装并运行 MongoDB。此外,使用
mongoose, express, body-parser
安装所需的 npm 包(npm install
等)。
如果您有任何其他问题或需要更多帮助,请随时联系。