简介
任务管理系统是一种常见的应用程序,它可以帮助我们记录和管理待办事项。在本文中,我们将使用 Node.js 构建一个简单的 To Do List 任务管理系统。本文适合初学者学习 Node.js,并希望构建基本 Web 应用程序。
技术栈
- Node.js:用于构建后端应用程序。
- Express.js:用于构建 Web 应用程序。
- MongoDB:用于存储数据。
- ejs:模板引擎。
环境搭建
为了开始构建我们的 To Do List 任务管理系统,我们需要确定环境。首先,我们需要安装 Node.js。在安装 Node.js 之后,我们可以使用 npm
包管理器来安装其他必要的软件包。
npm install express mongodb ejs
接下来,我们需要启动 MongoDB 实例。安装 MongoDB 并按照 MongoDB 官方文档 中的说明进行操作。然后,使用以下命令启动 MongoDB:
mongod --dbpath=/path/to/database
注意:/path/to/database
应该根据您的实际需要更改。
代码实现
应用程序配置
首先,让我们创建一个名为 app.js
的文件。在此文件中,设置应用程序配置。
// javascriptcn.com 代码示例 // 引入必要的模块 const express = require('express'); const path = require('path'); const mongoose = require('mongoose'); // 创建 Express 应用程序 const app = express(); // 设置渲染引擎 app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); // 配置静态文件路径 app.use(express.static(path.join(__dirname, 'public'))); // 获取请求体 app.use(express.urlencoded({ extended: true })); // 连接数据库 mongoose .connect('mongodb://localhost:27017/todo', { useNewUrlParser: true, useUnifiedTopology: true, }) .then(() => { console.log('Successful connection to MongoDB.'); }) .catch((err) => { console.log(err); }); // 启动应用程序 app.listen(3000, () => { console.log('Server started on port 3000.'); });
在上面的代码中,我们创建了一个 Express 应用程序并设置了应用程序配置。其中,我们用了 ejs
作为模板引擎。
创建模型
接下来,我们需要创建一个模型来描述数据库中的数据。在本例中,我们将创建一个名为 Task
的模型。
// javascriptcn.com 代码示例 const mongoose = require('mongoose'); const taskSchema = new mongoose.Schema( { name: { type: String, required: true, }, description: String, status: { type: String, enum: ['todo', 'doing', 'done'], default: 'todo', }, }, { timestamps: true, } ); const Task = mongoose.model('Task', taskSchema); module.exports = Task;
在上面的代码中,我们使用 Mongoose 创建了 Task
模型,并将其导出以供后续使用。该模型包含任务的名称、描述和状态。其中,status
字段是一个枚举值,转换为 'todo'
、'doing'
或者 'done'
的其中一个值。另外,我们使用了一个名为 timestamps
的选项,用于自动添加 createdAt
和 updatedAt
字段。
实现路由
现在我们将实现一些路由,用户将通过这些路由与应用程序进行交互。
渲染列表视图
首先,我们将创建视图,用于列出所有任务。在视图中,我们将能够查看任务的名称、描述和状态。然后,我们将创建一个路由来渲染列表视图。
首先,我们需要在应用程序根目录下的 views
文件夹中创建名为 index.ejs
的文件。代码如下:
// javascriptcn.com 代码示例 <!DOCTYPE html> <html> <head> <title>To Do List</title> </head> <body> <h1>To Do List</h1> <table> <thead> <tr> <th>Name</th> <th>Description</th> <th>Status</th> </tr> </thead> <tbody> <% tasks.forEach(function(task){ %> <tr> <td><%= task.name %></td> <td><%= task.description %></td> <td><%= task.status %></td> </tr> <% }); %> </tbody> </table> </body> </html>
然后,我们将创建一个路由,用于渲染列表视图。代码如下:
// javascriptcn.com 代码示例 const express = require('express'); const Task = require('./models/task'); const router = express.Router(); router.get('/', async (req, res) => { try { const tasks = await Task.find({}); res.render('index', { tasks }); } catch (err) { console.log(err); res.render('index', { tasks: [] }); } }); module.exports = router;
在上面的代码中,我们创建一个名为 '/'
的路由,并通过 Task.find({})
从数据库中获取所有任务。然后,我们将任务列表和视图名称作为参数传递给 res.render()
。
渲染新建任务表单
接下来,我们将创建一个表单,用于添加新的任务。在视图中,我们将看到一个表单,该表单允许我们输入任务的名称、描述和状态。然后,我们将创建一个路由,用于渲染新表单。
在应用程序根目录下的 views
文件夹中,创建一个名为 new_task.ejs
的文件。代码如下:
// javascriptcn.com 代码示例 <!DOCTYPE html> <html> <head> <title>New Task</title> </head> <body> <h1>New Task</h1> <form method="post" action="/tasks"> <label for="name">Name</label> <input type="text" id="name" name="name" required> <br> <label for="description">Description</label> <textarea id="description" name="description" rows="6"></textarea> <br> <label for="status">Status</label> <select id="status" name="status"> <option value="todo">To Do</option> <option value="doing">Doing</option> <option value="done">Done</option> </select> <br> <button type="submit">Create Task</button> </form> </body> </html>
然后,我们将创建一个路由,用于渲染新表单。代码如下:
// javascriptcn.com 代码示例 const express = require('express'); const router = express.Router(); router.get('/tasks/new', (req, res) => { res.render('new_task'); }); module.exports = router;
在上面的代码中,我们创建了一个名为 /tasks/new
的路由,并渲染了一个名为 new_task
的视图。
处理创建任务表单
接下来,我们将处理上一个步骤中的表单。我们将创建一个路由,用于为提交的表单创建新任务。当我们提交表单时,将发送 POST 请求,此路由将获取请求并将其保存在数据库中。
// javascriptcn.com 代码示例 const express = require('express'); const Task = require('./models/task'); const router = express.Router(); router.post('/tasks', async (req, res) => { const task = new Task({ name: req.body.name, description: req.body.description, status: req.body.status, }); try { await task.save(); res.redirect('/'); } catch (err) { console.log(err); res.render('new_task', { task }); } }); module.exports = router;
在上面的代码中,我们创建了一个名为 /tasks
的路由,并使用 Task.save()
将任务保存在数据库中。如果保存成功,我们将重定向到根路由。否则,将重新呈现表单。
渲染编辑任务表单
现在,我们将创建一个表单,用于编辑任务。这个表单将允许我们更改任务的名称、描述和状态。然后,我们将创建一个路由,用于渲染编辑表单。
在应用程序根目录下的 views
文件夹中,创建一个名为 edit_task.ejs
的文件。代码如下:
// javascriptcn.com 代码示例 <!DOCTYPE html> <html> <head> <title>Edit Task</title> </head> <body> <h1>Edit Task</h1> <form method="post" action="/tasks/<%= task._id %>?_method=PUT"> <label for="name">Name</label> <input type="text" id="name" name="name" value="<%= task.name %>" required> <br> <label for="description">Description</label> <textarea id="description" name="description" rows="6"><%= task.description %></textarea> <br> <label for="status">Status</label> <select id="status" name="status"> <% var statuses = ['todo', 'doing', 'done']; %> <% for(var i=0; i<statuses.length; i++) { %> <% if (statuses[i] === task.status) { %> <option value="<%= statuses[i] %>" selected><%= statuses[i].toUpperCase() %></option> <% } else { %> <option value="<%= statuses[i] %>"><%= statuses[i].toUpperCase() %></option> <% } %> <% } %> </select> <br> <button type="submit">Update Task</button> </form> </body> </html>
然后,我们将创建一个路由,用于渲染编辑表单。代码如下:
// javascriptcn.com 代码示例 const express = require('express'); const Task = require('./models/task'); const router = express.Router(); router.get('/tasks/:id/edit', async (req, res) => { try { const task = await Task.findById(req.params.id); res.render('edit_task', { task }); } catch (err) { console.log(err); res.redirect('/'); } }); module.exports = router;
在上面的代码中,我们创建了一个名为 /tasks/:id/edit
的路由,并使用 Task.findById()
查找要编辑的任务。如果成功查找到任务,我们将渲染名为 edit_task
的视图并将任务作为变量传递。
处理编辑任务表单
现在,我们将处理上一个步骤中的表单。我们将创建一个路由,用于更新任务。当我们提交表单时,将发送 PUT 请求,此路由将获取请求并将其更新到数据库中。
在应用程序根目录下的 views
文件夹中,创建一个名为 edit_task.ejs
的文件。代码如下:
// javascriptcn.com 代码示例 const express = require('express'); const Task = require('./models/task'); const router = express.Router(); router.put('/tasks/:id', async (req, res) => { let task; try { task = await Task.findById(req.params.id); task.name = req.body.name; task.description = req.body.description; task.status = req.body.status; await task.save(); res.redirect('/'); } catch (err) { console.log(err); if (task) { res.render('edit_task', { task }); } else { res.redirect('/'); } } }); module.exports = router;
在上面的代码中,我们创建了一个名为 /tasks/:id
的路由,并使用 Task.findById()
查找要更新的任务。然后,我们将使用 Task.save()
更新任务,并重定向到根路由。
删除任务
最后,我们将创建一个路由,用于删除任务。当我们想要删除一个任务时,我们将使用 DELETE 请求发送到该路由。
// javascriptcn.com 代码示例 const express = require('express'); const Task = require('./models/task'); const router = express.Router(); router.delete('/tasks/:id', async (req, res) => { try { await Task.findByIdAndDelete(req.params.id); res.redirect('/'); } catch (err) { console.log(err); res.redirect('/'); } }); module.exports = router;
在上面的代码中,我们创建了一个名为 /tasks/:id
的路由,并使用 Task.findByIdAndDelete()
删除任务。然后,我们将重定向到根路由。
应用程序集成
现在,我们已经创建了所有必要的路由,现在将集成到应用程序中。
// javascriptcn.com 代码示例 // 引入模块 const express = require('express'); const path = require('path'); const mongoose = require('mongoose'); const methodOverride = require('method-override'); const indexRouter = require('./routes/index'); const taskRouter = require('./routes/tasks'); // 创建 Express 应用程序 const app = express(); // 设置渲染引擎 app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); // 配置静态文件路径 app.use(express.static(path.join(__dirname, 'public'))); // 获取请求体 app.use(express.urlencoded({ extended: true })); // 方法重写 app.use(methodOverride('_method')); // 连接数据库 mongoose .connect('mongodb://localhost:27017/todo', { useNewUrlParser: true, useUnifiedTopology: true, }) .then(() => { console.log('Successful connection to MongoDB.'); }) .catch((err) => { console.log(err); }); // 加载路由 app.use('/', indexRouter); app.use('/', taskRouter); // 启动应用程序 app.listen(3000, () => { console.log('Server started on port 3000.'); });
在上面的代码中,我们将所有路由加载到应用程序中,并使用 methodOverride
中间件来解析 DELETE 和 PUT 请求。
完成以上工作后,我们现在可以使用 To Do List 任务管理系统。访问 http://localhost:3000/tasks
即可查看所有任务。使用表单添加新任务或编辑现有任务。
总结
在本文中,我们通过使用 Node.js、Express.js 和 MongoDB 构建 To Do List 任务管理系统,了解了如何使用 Node.js 进行 Web 应用程序开发。通过学习本文,您应该增强对以下方面的理解:
- 如何使用 Node.js 创建服务器端应用程序。
- 如何使用 Express.js 创建 Web 应用程序。
- 如何使用 MongoDB 存储和检索数据。
我们希望,借助本文,您能够更好的了解 Node.js 技术的应用,掌握构建实际应用的基本思路。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6531d91f7d4982a6eb3d39be