[英]MVC pattern - Node.js Express & MongoDB web application
[英]MVC - Adding Update Functionality to the Model - Node.js Express & MongoDB
我正在開發 Node.js Express & MongoDB web 應用程序。
實際上,我正在嘗試使用 MVC 功能。 但是,在我將更新功能添加到 model 之后,我的代碼出現了問題。
實際上,當我嘗試更新帖子時,我的應用程序崩潰了,並且收到以下錯誤消息:
TypeError: C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\admin\posts-list.ejs:19
17| <ol id="posts-list">
18| <% for (const post of posts) { %>
>> 19| <li><%- include('includes/post-item', { post: post }) %></li>
20| <% } %>
21| </ol>
22| <% } %>
C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\admin\includes\post-item.ejs:3
1| <article class="post-item">
2| <h2><%= post.title %></h2>
>> 3| <p class="post-item-author">Rédigé par <%= post.author.name %></p>
4| <p><%= post.summary %></p>
5| <div class="post-actions">
6| <form action="/blog/<%= post._id %>/delete" method="POST">
Cannot read properties of undefined (reading 'name')
at eval ("C:\\Users\\DELL\\Desktop\\node-com4muz-database-mvc\\views\\admin\\includes\\post-item.ejs":15:38)
at post-item (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\ejs\lib\ejs.js:703:17)
at include (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\ejs\lib\ejs.js:701:39)
at eval ("C:\\Users\\DELL\\Desktop\\node-com4muz-database-mvc\\views\\admin\\posts-list.ejs":29:17)
at posts-list (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\ejs\lib\ejs.js:703:17)
at tryHandleCache (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\ejs\lib\ejs.js:274:36)
at View.exports.renderFile [as engine] (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\ejs\lib\ejs.js:491:10)
at View.render (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\express\lib\view.js:135:8)
at tryRender (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\express\lib\application.js:657:10)
at Function.render (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\express\lib\application.js:609:3) {
path: 'C:\\Users\\DELL\\Desktop\\node-com4muz-database-mvc\\views\\admin\\posts-list.ejs'
}
實際上,在我更改 model 文件(見下文)和路由文件(見下文)中的代碼之前,更新功能運行良好。
這就是為什么我認為我們應該比較兩個代碼,在將更新功能添加到 model 之前和之后,以找出問題所在。
這是我在將更新功能添加到 model 之前的代碼:
路線\管理\博客.js:
const express = require('express');
const mongodb = require('mongodb');
const multer = require('multer');
const storageConfig = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/admin/images');
},
filename: function (req, file, cb) {
cb(null, Date.now() + '-' + file.originalname);
}
});
const db = require('../../data/database');
const Post = require('../../models/post');
const ObjectId = mongodb.ObjectId;
const upload = multer({ storage: storageConfig });
const router = express.Router();
router.get('/posts', async function (req, res) {
const posts = await db
.getDb()
.collection('posts')
.find({})
.project({ title: 1, summary: 1, 'author.name': 1 })
.toArray();
res.render('posts-list', { posts: posts });
});
router.get('/new-post', async function (req, res) {
const authors = await db.getDb().collection('authors').find().toArray();
res.render('create-post', { authors: authors });
});
router.post('/new-post', upload.single('image'), async function (req, res) {
const uploadedImageFile = req.file;
const authorId = new ObjectId(req.body.author);
const author = await db
.getDb()
.collection('authors')
.findOne({ _id: authorId });
const enteredTitle = req.body.title;
const enteredSummary = req.body.summary;
const enteredContent = req.body.content;
const date = new Date();
const selectedAuthor = {
author: {
id: authorId,
name: author.name,
email: author.email
}
};
const selectedImage = uploadedImageFile.path;
const post = new Post(
enteredTitle,
enteredSummary,
enteredContent,
date,
selectedAuthor.author,
selectedImage
);
await post.save();
res.redirect('/posts');
});
router.get('/blog/:id/edit', async function (req, res) {
const postId = req.params.id;
const post = await db
.getDb()
.collection('posts')
.findOne(
{ _id: new ObjectId(postId) },
{ title: 1, summary: 1, content: 1 }
);
if (!post) {
return res.status(404).render('404');
}
res.render('update-post', { post: post });
});
router.post('/blog/:id/edit', async function (req, res) {
const postId = new ObjectId(req.params.id);
const result = await db
.getDb()
.collection('posts')
.updateOne(
{ _id: postId },
{
$set: {
title: req.body.title,
summary: req.body.summary,
content: req.body.content
// date: new Date()
}
}
);
res.redirect('/posts');
});
router.post('/blog/:id/delete', async function (req, res) {
const postId = new ObjectId(req.params.id);
const result = await db
.getDb()
.collection('posts')
.deleteOne({ _id: postId });
res.redirect('/posts');
});
router.get('/admin', async function (req, res) {
if (!res.locals.isAuth) {
// if (!req.session.user)
return res.status(401).render('401');
}
if (!res.locals.isAdmin) {
return res.status(403).render('403');
}
res.render('admin');
});
module.exports = router;
模型\post.js:
const db = require('../data/database');
class Post {
constructor(title, summary, content, date, author, image, id) {
this.title = title;
this.summary = summary;
this.content = content;
this.date = date;
this.author = author;
this.image = image;
this.id = id; // may be undefined
}
async save() {
const newPost = {
title: this.title,
summary: this.summary,
content: this.content,
date: this.date,
author: this.author,
imagePath: this.image
};
const result = await db.getDb().collection('posts').insertOne(newPost);
// console.log(result);
return result;
}
}
module.exports = Post;
這是向 model 添加更新功能后的代碼:
路線\管理\博客.js:
const express = require('express');
const mongodb = require('mongodb');
const multer = require('multer');
const storageConfig = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/admin/images');
},
filename: function (req, file, cb) {
cb(null, Date.now() + '-' + file.originalname);
}
});
const db = require('../../data/database');
const Post = require('../../models/post');
const ObjectId = mongodb.ObjectId;
const upload = multer({ storage: storageConfig });
const router = express.Router();
router.get('/posts', async function (req, res) {
const posts = await db
.getDb()
.collection('posts')
.find({})
.project({ title: 1, summary: 1, content: 1, 'author.name': 1 })
.toArray();
res.render('posts-list', { posts: posts });
});
router.get('/new-post', async function (req, res) {
const authors = await db.getDb().collection('authors').find().toArray();
res.render('create-post', { authors: authors });
});
router.post('/new-post', upload.single('image'), async function (req, res) {
const uploadedImageFile = req.file;
const authorId = new ObjectId(req.body.author);
const author = await db
.getDb()
.collection('authors')
.findOne({ _id: authorId });
const enteredTitle = req.body.title;
const enteredSummary = req.body.summary;
const enteredContent = req.body.content;
const date = new Date();
const selectedAuthor = {
author: {
id: authorId,
name: author.name,
email: author.email
}
};
const selectedImage = uploadedImageFile.path;
const post = new Post(
enteredTitle,
enteredSummary,
enteredContent,
date,
selectedAuthor.author,
selectedImage
);
await post.save();
res.redirect('/posts');
});
router.get('/blog/:id/edit', async function (req, res) {
const postId = req.params.id;
const post = await db
.getDb()
.collection('posts')
.findOne(
{ _id: new ObjectId(postId) },
{ title: 1, summary: 1, content: 1 }
);
if (!post) {
return res.status(404).render('404');
}
res.render('update-post', { post: post });
});
router.post('/blog/:id/edit', async function (req, res) {
const enteredTitle = req.body.title;
const enteredSummary = req.body.summary;
const enteredContent = req.body.content;
const post = new Post(
enteredTitle,
enteredSummary,
enteredContent,
req.params.id
);
await post.save();
res.redirect('/posts');
});
router.post('/blog/:id/delete', async function (req, res) {
const postId = new ObjectId(req.params.id);
const result = await db
.getDb()
.collection('posts')
.deleteOne({ _id: postId });
res.redirect('/posts');
});
router.get('/admin', async function (req, res) {
if (!res.locals.isAuth) {
// if (!req.session.user)
return res.status(401).render('401');
}
if (!res.locals.isAdmin) {
return res.status(403).render('403');
}
res.render('admin');
});
module.exports = router;
模型\post.js:
const mongodb = require('mongodb');
const db = require('../data/database');
const ObjectId = mongodb.ObjectId;
class Post {
constructor(title, summary, content, date, author, image, id) {
this.title = title;
this.summary = summary;
this.content = content;
this.date = date;
this.author = author;
this.image = image;
if (id) {
this.id = new ObjectId(id);
}
}
async save() {
let result;
if (this.id) {
result = await db
.getDb()
.collection('posts')
.updateOne(
{ _id: postId },
{
$set: {
title: this.id,
summary: this.summary,
content: this.content
}
}
);
} else {
result = await db.getDb().collection('posts').insertOne({
title: this.title,
summary: this.summary,
content: this.content,
date: this.date,
author: this.author,
imagePath: this.image
});
}
return result;
}
}
module.exports = Post;
在/blog/:id/edit
路由下創建post
object 時,您將id
作為錯誤參數傳遞給它,它不會被拾取,因此它保存帖子,而不是更新它,從而使其他屬性未定義。
試試這個,在id
之前傳遞 3 undefined arguments,它作為/blog/:id/edit
路由下的最后一個參數傳遞:
const post = new Post(
enteredTitle,
enteredSummary,
enteredContent,
...[,,,], // pass 3 undefined arguments
req.params.id
);
await post.save();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.