[英]MVC - Adding Update Functionality to the Model - Node.js Express & MongoDB
[英]MVC pattern - Node.js Express & MongoDB web application
我正在開發 Nde.js Express & MongoDB web 應用程序。
我正在嘗試使用 MVC 模式來改進我的網站。
但是,在創建 model 后,我無法訪問某些頁面,並且在我的終端上收到以下錯誤消息:
類型錯誤:C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\home\posts.ejs:19 17| 18| <% for (const post of posts) { %>
19|
<%- include('includes/posts/post-item', { post: post }) %> 20| <% } %> 21| 22| <% } %>C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\home\includes\posts\post-item.ejs:4 2| " alt="" /> 3|
<%= post.title %>
4| 通過 <%= post.author.name %>
5|<%= post.summary %>
6| 7| ">查看帖子無法在評估時讀取未定義(讀取“名稱”)的屬性(“C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\home\includes\posts\post-item.ejs”:20:38 ) 在后項 (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\ejs\lib\ejs.js:703:17) 在包含 (C:\Users\DELL\Desktop\node -com4muz-database-mvc\node_modules\ejs\lib\ejs.js:701:39) 在 eval ("C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\home\posts.ejs" :29:17) 在帖子 (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\ejs\lib\ejs.js:703:17) 在 tryHandleCache (C:\Users\DELL\Desktop) \node-com4muz-database-mvc\node_modules\ejs\lib\ejs.js:274:36) 在 View.exports.renderFile [作為引擎] (C:\Users\DELL\Desktop\node-com4muz-database-mvc \node_modules\ejs\lib\ejs.js:491:10) 在 View.render (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\express\lib\view.js:135:8 ) 在 tryRender (C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\express\lib\application.js:657:10) 在 Function.render ( C:\Users\DELL\Desktop\node-com4muz-database-mvc\node_modules\express\lib\application.js:609:3) { 路徑:'C:\Users\DELL\Desktop\node-com4muz-database- mvc\views\home\posts.ejs' }
我希望有人通過比較兩個版本來幫助我找到代碼中的問題所在:MVC 模式之前和 MVC 模式之后。
在 MVC 模式之前:
routes\admin\blog.js 從第 37 行到第 62 行:
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 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 newPost = {
title: req.body.title,
summary: req.body.summary,
body: req.body.content,
date: new Date(),
author: {
id: authorId,
name: author.name,
email: author.email
},
imagePath: uploadedImageFile.path
};
const result = await db.getDb().collection('posts').insertOne(newPost);
// console.log(result);
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, body: 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,
body: 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;
MVC模式之后:
routes\admin\blog.js 從第 69 行到第 72 行:
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,
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, body: 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,
body: 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;
事實上,我已經創建了一個 model 來使用我創建新帖子的帖子路由。 這是我寫的代碼:
模型\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.autor = 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;
之前,我更改了 MVC 模式之前的第一個版本的代碼,網站運行正常。
現在,錯誤表明views\home\includes\posts\post-item.ejs
post.author.name
的 post.author.name 不再被定義。
查看博客頁面請找相關代碼:
views\home\posts.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('../admin/includes/head', { title: 'Blog - Tous Les Articles' })
%>
<link rel="stylesheet" href="/admin/styles/posts.css" />
</head>
<body>
<%- include('../admin/includes/header') %>
<main id="all-posts">
<h1>Nos Articles</h1>
<% if (!posts || posts.length === 0) { %>
<p>Aucun article trouvé - peut-être voulez-vous en créer un ?</p>
<a class="btn" href="/new-post">Create a new Post</a>
<% } else { %>
<ol id="posts-list">
<% for (const post of posts) { %>
<li><%- include('includes/posts/post-item', { post: post }) %></li>
<% } %>
</ol>
<% } %>
</main>
</body>
</html>
views\home\includes\posts\post-item.ejs:
<article class="post-item">
<img src="<%= post.imagePath %>" alt="<%= post.title %>" />
<h2><%= post.title %></h2>
<p class="post-item-author">By <%= post.author.name %></p>
<p><%= post.summary %></p>
<div class="post-actions">
<a class="btn" href="/blog/<%= post._id %>">View Post</a>
</div>
</article>
我通過在selectedAuthor
常量上調用author
object 解決了這個問題,如下面的第 28 行:
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');
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.