简体   繁体   English

MVC 模式 - Node.js Express & MongoDB web 应用

[英]MVC pattern - Node.js Express & MongoDB web application

I'm developing a Nde.js Express & MongoDB web application.我正在开发 Nde.js Express & MongoDB web 应用程序。

I'm trying to use the MVC pattern to improve my website.我正在尝试使用 MVC 模式来改进我的网站。

However, after creating a model, I can't access some pages and I get the following error message on my terminal:但是,在创建 model 后,我无法访问某些页面,并且在我的终端上收到以下错误消息:

TypeError: C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\home\posts.ejs:19 17|类型错误:C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\home\posts.ejs:19 17| 18| 18| <% for (const post of posts) { %> <% for (const post of posts) { %>

19| 19|

  • <%- include('includes/posts/post-item', { post: post }) %> <%- include('includes/posts/post-item', { post: post }) %>
  • 20| 20| <% } %> 21| <% } %> 21| 22| 22| <% } %> <% } %>

    C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\home\includes\posts\post-item.ejs:4 2| C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\home\includes\posts\post-item.ejs:4 2| " alt="" /> 3| " alt="" /> 3|

    <%= post.title %> <%= post.title %>

    4| 4| By <%= post.author.name %>通过 <%= post.author.name %>

    5| 5|

    <%= post.summary %> <%= post.summary %>

    6| 6| 7| 7| ">View Post ">查看帖子

    Cannot read properties of undefined (reading 'name') at eval ("C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\home\includes\posts\post-item.ejs":20: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\home\posts.ejs":29:17) at posts (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\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) { path: 'C:\Users\DELL\Desktop\node-com4muz-database-mvc\views\home\posts.ejs' } 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' }

    I would like someone to help me find where is the issue in my code by comparing both versions: before the MVC pattern and after the MVC pattern.我希望有人通过比较两个版本来帮助我找到代码中的问题所在:MVC 模式之前和 MVC 模式之后。

    Before the MVC pattern:在 MVC 模式之前:

    routes\admin\blog.js from line 37 to line 62: 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;
    

    After the MVC pattern: MVC模式之后:

    routes\admin\blog.js from line 69 to line 72: 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;
    

    Indeed, I have created a model to use the post route where I create new post.事实上,我已经创建了一个 model 来使用我创建新帖子的帖子路由。 Here is the code I wrote:这是我写的代码:

    models\post.js:模型\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;
    

    Before, I changed the code from the first version before the MVC pattern, the website was working fine.之前,我更改了 MVC 模式之前的第一个版本的代码,网站运行正常。

    Now, the error says that post.author.name in views\home\includes\posts\post-item.ejs is not defined anymore.现在,错误表明views\home\includes\posts\post-item.ejs post.author.name的 post.author.name 不再被定义。

    Please find the code related to view the blog page:查看博客页面请找相关代码:

    views\home\posts.ejs: 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: 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>
    

    I fixed this issue by calling the author object on the selectedAuthor constant as below at line 28:我通过在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.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM