簡體   English   中英

MVC - 向 Model 添加更新功能 - Node.js Express & MongoDB

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM