MongoDB+模板引擎 项目实例-学生档案管理

目标:模板引擎应用,强化 node.js 项目制作流程。

知识点:http请求响应、数据库、模板引擎、静态资源访问。

1、建立项目文件夹并生成项目描述文件 package.json

1.1、创建 students 文件夹

1.2、生成项目描述文件 package.json

在命令行工具中切换到当前项目的根目录下,输入:

npm init -y

2、创建网站服务器,实现客户端和服务器端通信

2.1、创建网站服务器

在根目录下新建 app.js 文件:

// 引入 http 模块
const http = require('http');
// 创建网站服务器
const app = http.createServer();

2.2、添加请求事件,实现通信

// 引入 http 模块
const http = require('http');
// 创建网站服务器
const app = http.createServer();
// 当客户端访问服务器端的时候
app.on('request', (req, res) => {
  res.end('ok');
});

app.listen(80);
console.log('服务器启动成功');

在命令行工具中开启服务器:

nodemon app.js

再打开浏览器,输入:http://localhost/

可以看到,响应成功:

3、连接数据库并根据需求设计学员信息表

3.1、连接数据库

1、安装 mongoose,在命令行工具中输入:

npm install mongoose

然后重启开启服务器:nodemon app.js

2、连接数据库

在 app.js 文件中添加:

// 引入 http 模块
const http = require('http');
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true, useUnifiedTopology: true})
  .then(() => console.log('数据库连接成功'))
  .catch(() => console.log('数据库连接失败'))
// 创建网站服务器
const app = http.createServer();
// 当客户端访问服务器端的时候
app.on('request', (req, res) => {
  res.end('ok');
});

app.listen(80);
console.log('服务器启动成功');

然后在命令行工具中可以看到:数据库连接成功的提示。

注意:如果没启动 MongoDB,记得要先启动:net start mongoDB

我们上次说过要把数据库的代码分离出去,不要都写在一个文件中

所以新建 model 文件夹,创建 connect.js 文件,然后把数据库连接部分的代码剪切过来。

const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true, useUnifiedTopology: true})
  .then(() => console.log('数据库连接成功'))
  .catch(() => console.log('数据库连接失败'))

然后回到 app.js 中导入connect

require('./model/connect');

3.2、设计学员信息表

1、设计用户集合用到的字段

在 model 目录下新建 user.js 文件:

const mongoose = require('mongoose');
// 创建学生集合规则
const studentsSchema = new mongoose.Schema({
  name:{
    type: String,
    required: true,
    minlength: 2,
    maxlength: 10
  },
  age: {
    type: Number,
    min: 10,
    max: 25
  },
  sex: {
    type:String
  },
  email: String,
  hobbies: [String],
  collage: String,
  enterDate: {
    type: Date,
    default: Date.now
  }
});
// 创建学生信息集合
const Student = mongoose.model('Student', studentsSchema);
// 将学生信息集合进行导出
module.exports = Student;

回到 app.js 文件中,导入 Student 

const Student = require('./model/user');

4、创建路由并实现页面模板呈递

第三方模块 router

功能:实现路由。

使用步骤:

1、获取路由对象

2、调用路由对象提供的方法创建路由

3、启用路由,使路由生效

示例代码:

const getRouter = require('router');
const router = getRouter();
router.get('/add', (req, res) => {
  res.end('hello world')
})
server.on('request', (req. res) => {
  router(req, res)
})

下载安装:

npm install router

重新启动项目:nodemon app.js

回到app.js 文件中,引入 router 模块:

// 引入 router 模块
const getRouter = require('router');
// 获取路由对象
const router = getRouter();

router.get('/test', (req, res) => {
  res.end('test')
})
router.get('/index', (req, res) => {
  res.end('index')
})

// 当客户端访问服务器端的时候
app.on('request', (req, res) => {
  // res.end('ok');
  router(req, res, () => {
  })
});

此时打开浏览器,输入:http://localhost/test,页面上可以看到 test ;同样输入 http://localhost/index,页面可以显示index。

4.1、创建当前项目路由

// 添加学生档案信息页面
router.get('/add', (req, res) => {
  res.end('add')
})
// 学生档案信息列表页面
router.get('/list', (req, res) => {
  res.end('list')
})

4.2、呈现对应的页面

1、安装模板引擎

在命令行工具输入:npm install art-template

在项目根目录下,新建 views 文件夹, 把静态页面粘贴过来;并在项目根目录下,新建 public 文件夹,把 css 文件站提过来。

在 app.js 文件中引入模板引擎:

const template = require('art-template');

接下来在对应的路由中,渲染模板引擎,并把渲染的结果响应给客户端

2、配置模板的根目录

const path = require('path');

// 配置模板的根目录
template.defaults.root = path.join(__dirname, 'views');

// 添加学生档案信息页面
router.get('/add', (req, res) => {
  const html = template('index.art', {})
  res.end(html)
})
// 学生档案信息列表页面
router.get('/list', (req, res) => {
  const html = template('list.art', {})
  res.end(html)
})

在命令行工具开启服务:nodemon app.js

回到浏览器中,输入:http://localhost/add

会发现i服务器一直请求,点击刷新按钮,可以看到没有样式,查看源码可以看到页面还引用了一个 css 样式文件。

第三方模块 serve-static

功能:实现静态资源访问服务。

步骤:

1、引入 serve-static 模块获取创建静态资源服务功能的方法

2、调用方法创建静态资源服务并指定静态资源服务目录

3、启动静态资源服务功能

示例代码:

const serveStatic = require('serve-static')
const serve = serveStatic('public')
server.on('request', () => {
  serve(req. res)
})
server.listen(3000)

5、实现静态资源访问

5.1、下载安装 serve-static

npm install serve-static

5.2、引入静态资源访问 serve-static 模块

// 引入静态资源访问模块
const serveStatic = require('serve-static');

5.3、实现静态资源访问服务

// 实现静态资源访问服务
const serve = serveStatic(path.join(__dirname, 'public'));

5.4、启用静态资源访问服务功能

// 当客户端访问服务器端的时候
app.on('request', (req, res) => {
  // 启用路由功能
  router(req, res, () => {})
  // 启用静态资源访问服务功能
  serve(req, res, () => {})
});

回到浏览器刷新页面,可以看到样式出来了:

6、实现学生信息添加功能

6.1、在模板的表单中指定请求地址与请求方式

打开 views 目录下的 index.art 文件,添加请求地址及请求方式

<form method="post" action="/add">

6.2、为每一个表单项添加 name 属性

<input class="normal" type="text" autofocus placeholder="请输入姓名" name="name">

<input class="normal"  type="text" placeholder="请输入年龄" name="age">

<input type="radio" value="0" name="sex"><input type="radio" value="1" name="sex"><input class="normal" type="text" placeholder="请输入邮箱地址" name="email">

<input type="checkbox" value="0" name="hobbies"> 敲代码
<input type="checkbox" value="1" name="hobbies"> 打篮球
<input type="checkbox" value="1" name="hobbies"> 睡觉

<select class="normal" name="collage">

<input type="date" class="normal" name="enterDate"> 

6.3、添加实现学生信息功能路由

// 实现学生信息添加功能路由
router.post('/add', (req, res) => {
 
})

6.4、接收客户端传递过来的学生信息

// 实现学生信息添加功能路由
router.post('/add', (req, res) => {
  // 接收用户提交的信息
  let fromData= '';
  // 当有参数传递的时候会触发 data 事件
  req.on('data', param => {
    fromData += param;
  });
  // 当参数接收完毕的时候会触发 end 事件
  req.on('end', async () => {
    console.log(querystring.parse(fromData))
    res.end('123');
  });
})

回到浏览器中刷新页面,随便输入一些信息后提交;然后可以看到页面显示:123

打开命令行工具,可以看到:参数已经接受过来了

6.5、将学生信息添加到数据库中

// 实现学生信息添加功能路由
router.post('/add', (req, res) => {
  // 接收用户提交的信息
  let fromData= '';
  // 当有参数传递的时候会触发 data 事件
  req.on('data', param => {
    fromData += param;
  });
  // 当参数接收完毕的时候会触发 end 事件
  req.on('end', async () => {
    // 将用户提交的信息添加到数据库中
    await Student.create( querystring.parse(fromData));
    // 重定向 状态码是301
    // Location 跳转地址
    res.writeHead(301, {
      Location: '/list'
    });
    res.end();
  });
}) 

6.6、将页面信息重定向到学生信息列表页面

回到浏览器中刷新页面,重新提交一些信息后,会重定向到 /list 路由

打开 Compass 软件,可以看到 playground 下多了一个 students 集合,里面有一条刚提交的数据

7、实现学生信息展示功能

7.1、从数据库中将所有的学生信息查询出来

在 app.js 中继续编辑代码:

// 学生档案信息列表页面
router.get('/list', async (req, res) => {
  // 查询用户信息
  let students = await Student.find()
  console.log(students);

  const html = template('list.art', {})
  res.end(html)
})

回到浏览器中刷新 /list 页面,在命令行工具中可以看到:

 

7.2、通过模板引擎将学生信息和 HTML 模板进行拼接

继续编辑 app.js 文件:

// 学生档案信息列表页面
router.get('/list', async (req, res) => {
  // 查询用户信息
  let students = await Student.find()
  console.log(students);

  const html = template('list.art', {
    students: students
  })
  res.end(html)
})

打开 list.art 文件,添加循环:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>学员信息</title>
    <link rel="stylesheet" href="./css/list.css">
</head>
<body>
    <table>
        <caption>学员信息</caption>
        <tr>
            <th>姓名</th>
            <th>年龄</th>
            <th>性别</th>
            <th>邮箱地址</th>
            <th>爱好</th>
            <th>所属学院</th>
            <th>入学时间</th>
        </tr>
        {{each students}}
        <tr>
            <th>{{$value.name}}</th>
            <th>{{$value.age}}}</th>
            <th>{{$value.sex}}</th>
            <th>{{$value.email}}</th>
            <th>{{$value.hobbies}}</th>
            <th>{{$value.collage}}</th>
            <th>{{$value.enterDate}}</th>
        </tr>
        {{/each}}
    </table>
</body>
</html>

回到浏览器刷新 /list 页面,可以看到数据渲染出来了:

这里可以看出三个问题:性别、爱好、入学时间。

7.3、将拼接好的 HTML 模板响应给客户端

解决性别问题:

<th>{{$value.sex == '0' ? '男' : '女'}}</th>

解决爱好问题:

打开 index.art 文件,修改下:

爱好: 
<input type="checkbox" value="敲代码" name="hobbies"> 敲代码
<input type="checkbox" value="打篮球" name="hobbies"> 打篮球
<input type="checkbox" value="睡觉" name="hobbies"> 睡觉

再重新添加一条学生信息:

可以看到爱好已经显示了,但是格式还是不对,还要进行处理:

<th>
    {{each $value.hobbies}}
     <span>{{$value}}</span>
    {{/each}}
</th>

刷新浏览器,可以看到:爱好的格式已经正常了

解决时间问题:

第三方模板 dateformat 处理时间格式

下载安装:

npm install dateformat

然后重新开启服务:nodemon app.js

修改 app.js 文件:

// 引入处理日期的第三方模块
const dateFormat = require('dateformat');

// 导入模板变量 处理日期格式的方法
template.defaults.imports.dateFormat = dateFormat;

回到 list.art 文件:

<th>{{dateFormat($value.enterDate, "yyyy-mm-dd hh:mm")}}</th>

在浏览器刷新页面,可以看到:日期格式也正常了

此时功能都实现了。

但是发现 app.js 中路由部分的代码还可以分离出去

新建 route 目录,并在目录下 新建 index.js 文件,把 app.js 中路由部分的代码剪切过来:

// 引入 router 模块
const getRouter = require('router');
// 获取路由对象
const router = getRouter();
// 学生信息集合
const Student = require('../model/user');
// 引入模板引擎
const template = require('art-template');
// 处理请求参数模块
const querystring = require('querystring');

// 添加学生档案信息页面
router.get('/add', (req, res) => {
  const html = template('index.art', {})
  res.end(html)
})
// 学生档案信息列表页面
router.get('/list', async (req, res) => {
  // 查询用户信息
  let students = await Student.find()
  console.log(students);

  const html = template('list.art', {
    students: students
  })
  res.end(html)
})
// 实现学生信息添加功能路由
router.post('/add', (req, res) => {
  // 接收用户提交的信息
  let fromData= '';
  // 当有参数传递的时候会触发 data 事件
  req.on('data', param => {
    fromData += param;
  });
  // 当参数接收完毕的时候会触发 end 事件
  req.on('end', async () => {
    // 将用户提交的信息添加到数据库中
    await Student.create( querystring.parse(fromData));
    // 重定向 状态码是301
    // Location 跳转地址
    res.writeHead(301, {
      Location: '/list'
    });
    res.end();
  });
})

module.exports = router;

修改后的 app.js 文件:

// 引入 http 模块
const http = require('http');
// 引入模板引擎
const template = require('art-template');
// 引入 path 慕课
const path = require('path');
// 引入静态资源访问模块
const serveStatic = require('serve-static');
// 引入处理日期的第三方模块
const dateFormat = require('dateformat');

const router = require('./route/index');

// 实现静态资源访问服务
const serve = serveStatic(path.join(__dirname, 'public'));

// 配置模板的根目录
template.defaults.root = path.join(__dirname, 'views');
// 导入模板变量 处理日期格式的方法
template.defaults.imports.dateFormat = dateFormat;

// 数据库连接
require('./model/connect');

// 创建网站服务器
const app = http.createServer();
// 当客户端访问服务器端的时候
app.on('request', (req, res) => {
  // 启用路由功能
  router(req, res, () => {})
  // 启用静态资源访问服务功能
  serve(req, res, () => {})
});

app.listen(80);
console.log('服务器启动成功');

回到浏览器刷新,重新测试下功能。OK,没有影响,都正常。

posted on 2020-12-07 16:18  JoeYoung  阅读(528)  评论(5编辑  收藏  举报