网站首页 » 前端开发 » JavaScript » ejs+Egg.js+MongoDB 搭建极简版个人博客(增删改查)
上一篇:
下一篇:

ejs+Egg.js+MongoDB 搭建极简版个人博客(增删改查)

前言

上一篇博文中分享了Vue+Express+MongoDB 搭建极简版个人博客(增删改查),从中接触到了 Egg.js 所以也顺便把 Egg.js 也先简单地玩一下,同样的,接下来要展示的示例也是数据的增删改查,非常地简单,只是想通过这些简单的过程来粗略地认识下 Egg.js。

个人博客搭建之旅

这个也没什么好说的,直接进入主题。

涉及到的技术栈:

  • Egg.js
  • MongoDB
  • mongoose
  • ejs
文件结构
├── app
│   ├── controller
│   │  ├── home.js
│   │  └── post.js
│   ├── model
│   │  └── post.js
│   ├── service
│   │  └── post.js
│   ├── view
│   │  ├── home.html
│   │  └── editPost.html
│   └── router.js
└── config
    ├── config.default.js
    └── plugin.js

接下来我们看代码:

controller/home.js
'use strict';
const Controller = require('egg').Controller;

class HomeController extends Controller {
  async index() {
    const dataList = await this.service.post.findAll();
    // 这里需要注意的是,给模板传的参数是一个对象,然后就可以在模板中通过对象中的 key 键来获取相应的值
    await this.ctx.render('home.html', {
      dataList
    })
  }
}
module.exports = HomeController;
controller/post.js
'use strict';
const Controller = require('egg').Controller;
class EditPostController extends Controller {
    // 跳转到编辑页时执行的方法
    async index() {
        // 这种写法是 ES6 中的解构赋值
        const { ctx } = this;
        // 渲染编辑页并传参
        await ctx.render('edit', {
            status: "add"
        });
    }

    // 跳转到编辑页时执行的方法
    async edit() {
        const {ctx} = this;
        const aId = ctx.params.id;
        const article = await this.service.post.findById(aId);
        // 如果找到这篇文章
        if (article) {
            // 这里渲染的时候一定要传一个id 到页面,不然跳转后就没法通过 this.ctx.params 来获取到 id 的值
            await ctx.render('edit', {
                id:aId,
                status: 'edit',
                title: article.title,
                content: article.content
            });
        } else {
            console.log('文章不存在或者已删除');
        }
    }

    // 更新一篇文章
    async update() {
        const {ctx,service} = this;
        const id = ctx.params.id;
        // 通过 ctx 上下文拿到请求的相关字段
        const title = ctx.request.body.title;
        const content = ctx.request.body.content;
        let post = {
            title: title,
            content: content
        };
        await service.post.findAndUpdate(id, post);
        // 跳转到首页
        ctx.redirect('/');
    }

    // 删除一篇文章
    async delete() {
        const {ctx,service} = this;
        const id = ctx.params.id;
        await service.post.findAndRemove(id);
        ctx.redirect('/');
    }

    // 创建一篇文章
    async create() {
        const {
            ctx,
            service
        } = this;

        // 通过ctx上下文拿到请求的相关字段
        const title = ctx.request.body.title;
        const content = ctx.request.body.content;
        let post = {
            title: title,
            content: content
        };
        await service.post.create(post);
        ctx.redirect('/');
    }
}
module.exports = EditPostController;
model/post.js
'use strict';
module.exports = app => {
    const mongoose = app.mongoose;
    const Schema = mongoose.Schema;
    const PostSchema = new Schema({
        title: {
            type: String
        },
        content: {
            type: String
        }
    });
    return mongoose.model('Post', PostSchema);
}
service/post.js
'use strict';
const Service = require('egg').Service;
class PostService extends Service {
    // 获取所有文章
    async findAll() {
        // 这里需要注意: 只有安装了 mongoose 后, model 才会挂载到 this.ctx 上。
        return this.ctx.model.Post.find().sort({_id:-1}).exec();
    }

    // 保存文章
    async create(post) {
        this.ctx.model.Post.create(post);
    }

    // 获取指定文章
    async findById(id) {
        return this.ctx.model.Post.findById(id).exec();
    }

    // 获取指定文章
    async findAndUpdate(id, post) {
        this.ctx.model.Post.findOneAndUpdate({_id: id}, post).exec();
    }

    // 删除指定文章
    async findAndRemove(id) {
        this.ctx.model.Post.remove({_id: id},function (err) {
            console.log(err);
        });
    }
}
module.exports = PostService;
view/edit.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>编辑</title>
</head>
<body>
<% if (status !== undefined && status === 'edit') { %>
<form action='/post/update/<%= id %>' method='post'>
    <% } else { %>
    <form action='/post/create' method='post'>
        <% }  %>
        <div>
            <label>标题:</label>
            <div> <textarea rows="1" style="resize: none" name="title"><%= typeof title !== 'undefined' && title || '' %></textarea></div>
        </div>
        <div>
            <label>内容:</label>
            <div> <textarea name="content" id="" cols="30" rows="10"><%= typeof content !== 'undefined' && content || '' %></textarea></div>
        </div>
        <input type="submit" value="提交">
        <input type='hidden' name='_csrf' value='<%= ctx.csrf %>' />
        <!-- 关于ctx.csrf 的可以看官方这里的介绍 https://eggjs.org/zh-cn/core/security.html 安全篇 -->
    </form>
</body>
</html>
view/home.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>入门 Egg.js</title>
</head>
<body>
    <a href="/post">新增</a>
    <% dataList.forEach(function(item){ %>
        <li>
            <%= item.title %> <a href="/post/<%= item._id %>">编辑</a> <a href="/post/delete/<%= item._id %>">删除</a>
        </li>
        <% }); %>
</body>
</html>
router.js
'use strict';
/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const {
    router,
    controller
  } = app;
  router.get('/', controller.home.index);
  router.get('/post', controller.post.index);
  router.get('/post/:id', controller.post.edit);
  router.get('/post/delete/:id', controller.post.delete);
  router.post('/post/update/:id', controller.post.update);
  router.post('/post/create', controller.post.create);
};
config/config.default.js
'use strict';
module.exports = appInfo => {
  const config = exports = {};
  // use for cookie sign key, should change to your own and keep security
  config.keys = appInfo.name + '_1523196159518_2034';
  config.view = {
    mapping: {
      '.html': 'ejs',
    },
  };
  // add your config here
  config.middleware = [];
    
  /**
   * @see http://mongodb.github.io/node-mongodb-native/2.2/api/Db.html#createCollection
   */
  config.mongoose = {
    url: process.env.EGG_MONGODB_URL || 'mongodb://127.0.0.1:27017/blog',
    options: {
      server: {
        poolSize: 20
      },
    },
  };
  return config;
};
config/plugin.js
'use strict';
// had enabled by egg
// exports.static = true;
exports.ejs = {
    enable: true,
    package: 'egg-view-ejs',
};
exports.mongoose = {
    enable: true,
    package: 'egg-mongoose',
};

这样一真趟走下来,个人感受用 ejs 模板引擎来开发有点别扭,不是很方便。使用上,虽然作用的标签不多,但是要敲的代码比较多,并且只是为了让一个变量输出,或者作一点条件判断,你都得把变量或者表达式放到 <%=  %>或者<% %> 中,使用起来过于笨重。

相关资料

Node.js + Express.js 环境配置

mongoose 安装及配置

MongoDB 在 window 下安装及配置方法

mongoose 文档

 

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/ejs-eggjs-mongodb-build-minimalist-blog/

Leave a Reply

Your email address will not be published. Required fields are marked *

评论 END