Node.js+MongoDB+hbs基于async-await的CRUD更新删除操作实现咨询
运行前置准备
- 需提前安装依赖包:
express、mongoose、express-handlebars、method-override(浏览器form默认仅支持GET/POST请求,该中间件用于支持PUT/DELETE请求,多数更新删除报错都是漏装该依赖导致) - 本地需启动MongoDB服务
1. Mongoose 数据模型定义
以Todo业务场景为例,代码路径models/Todo.js:
const mongoose = require('mongoose'); const todoSchema = new mongoose.Schema({ title: { type: String, required: true }, content: { type: String, required: true }, createdAt: { type: Date, default: Date.now } }); module.exports = mongoose.model('Todo', todoSchema);
2. Express 服务及路由配置
代码路径app.js:
const express = require('express'); const mongoose = require('mongoose'); const exphbs = require('express-handlebars'); const methodOverride = require('method-override'); const Todo = require('./models/Todo'); const app = express(); // 连接MongoDB mongoose.connect('mongodb://localhost:27017/todoDB', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('MongoDB连接成功')) .catch(err => console.log(err)); // 配置handlebars模板引擎 app.engine('hbs', exphbs.engine({ extname: 'hbs' })); app.set('view engine', 'hbs'); // 全局中间件配置 app.use(express.urlencoded({ extended: true })); app.use(methodOverride('_method')); // 解析PUT/DELETE请求的核心配置 // GET请求:查询所有数据渲染首页 app.get('/', async (req, res) => { // .lean()将mongoose文档对象转为普通JS对象,否则hbs无法读取属性 const todos = await Todo.find().lean(); res.render('index', { todos }); }); // POST请求:新增数据 app.post('/todos', async (req, res) => { await Todo.create(req.body); res.redirect('/'); }); // GET请求:跳转编辑页 app.get('/todos/edit/:id', async (req, res) => { const todo = await Todo.findById(req.params.id).lean(); res.render('edit', { todo }); }); // PUT请求:更新数据 app.put('/todos/:id', async (req, res) => { await Todo.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true // 开启字段校验,避免非法数据入库 }); res.redirect('/'); }); // DELETE请求:删除数据 app.delete('/todos/:id', async (req, res) => { await Todo.findByIdAndDelete(req.params.id); res.redirect('/'); }); const PORT = 3000; app.listen(PORT, () => console.log(`服务运行在 http://localhost:${PORT}`));
3. Handlebars 模板文件
3.1 首页模板 路径views/index.hbs
<h1>Todo列表</h1> <!-- 新增表单 --> <form action="/todos" method="POST"> <div> <label>标题:</label> <input type="text" name="title" required> </div> <div> <label>内容:</label> <textarea name="content" required></textarea> </div> <button type="submit">新增</button> </form> <hr> <!-- 数据列表 --> {{#each todos}} <div style="border:1px solid #eee; padding:12px; margin:10px 0;"> <h3>{{title}}</h3> <p>{{content}}</p> <p>创建时间:{{createdAt}}</p> <a href="/todos/edit/{{_id}}">编辑</a> <!-- 删除表单 --> <form action="/todos/{{_id}}?_method=DELETE" method="POST" style="display:inline;margin-left:10px;"> <button type="submit" onclick="return confirm('确定删除吗?')">删除</button> </form> </div> {{/each}}
3.2 编辑页模板 路径views/edit.hbs
<h1>编辑Todo</h1> <form action="/todos/{{todo._id}}?_method=PUT" method="POST"> <div> <label>标题:</label> <input type="text" name="title" value="{{todo.title}}" required> </div> <div> <label>内容:</label> <textarea name="content" required>{{todo.content}}</textarea> </div> <button type="submit">保存修改</button> <a href="/" style="margin-left:10px;">取消</a> </form>
常见报错修复方案
- 请求404/方法不允许:检查是否配置了
method-override中间件,表单的_method参数拼写是否正确 - 模板页变量不显示:查询数据时是否加了
.lean(),mongoose返回的文档对象hbs无法直接读取 - 更新时字段校验失效:
findByIdAndUpdate方法是否加了runValidators: true配置
内容的提问来源于stack exchange,提问作者neo kiyo
相关产品推荐
相关产品推荐

