npm init -y
根目录下创建views目录,public目录,app.js文件,views目录下创建index.html文件
安装art-template和依赖
npm i art-template express-art-template --save
快速搭建
let express = require('express')
let app = express()
app.engine('html', require('express-art-template'))
app.get('/', function (req, res) {
res.render('index.html')
})
app.listen(3000, function () {
console.log('app is running')
})
路由设计和封装路由模块
路由模块中需要很多数据操作,所以把这些数据操作封装到student.js中
新建db.json文件
{
"students": [
{
"id": 1,
"name": "张三",
"gender": 0,
"age": 18,
"hobbies": "唱,跳"
}, {
"id": 2,
"name": "张三",
"gender": 0,
"age": 18,
"hobbies": "唱,跳"
}, {
"id": 3,
"name": "张三",
"gender": 0,
"age": 18,
"hobbies": "唱,跳"
},
{
"id": 4,
"name": "张三",
"gender": 0,
"age": 18,
"hobbies": "唱,跳"
}
]
}
整体目录
app.js
let express = require('express')
let router = require('./router')
let bodyParser = require('body-parser')
let app = express()
app.engine('html', require('express-art-template'))
app.use('/node_modules/', express.static('./node_modules/'))
app.use('/public/', express.static('./public/'))
// 解析 application/json
app.use(bodyParser.json());
// 解析 application/x-www-form-urlencoded
app.use(bodyParser.urlencoded());
app.use(router)
app.listen(3000, function () {
console.log('app is running')
})
router.js
let fs = require('fs')
let express = require('express')
let router = express.Router()
let Students = require('./student')
// 首页
router.get('/students', function (req, res) {
Students.find(function (err, students) {
if (err) {
return res.status(500).send('Server error')
}
res.render('index.html', {
food: [
'芋艿', '芋艿', '芋艿', '芋艿'
],
students: students
})
})
})
// 添加学生页面
router.get('/students/new', function (req, res) {
res.render('new.html')
})
// 添加学生后,发送学生数据表单
router.post('/students/new', function (req, res) {
Students.save(req.body, function (err) {
if (err) {
return res.status(500).send('添加学生失败')
}
})
console.log('添加学生成功')
res.redirect('/students')
})
// 编辑学生页面
router.get('/students/edit', function (req, res) {
Students.findOne(parseInt(req.query.id), function (err, student) {
if (err) {
return res.status(500).send('Server error')
}
res.render('edit.html', {
student: student
})
})
})
// 编辑学生页面后,发送学生数据表单
router.post('/students/edit', function (req, res) {
let student = req.body
student.id = parseInt(req.body.id)
Students.update(student, function (err) {
if (err) {
return res.status(500).send('编辑学生失败')
}
})
console.log('编辑学生成功')
res.redirect('/students')
})
// 删除学生
router.get('/students/delete', function (req, res) {
let id = parseInt(req.query.id)
Students.delete(id, function (err) {
if (err) {
return res.status(500).send('删除学生失败')
}
res.redirect('/students')
})
})
module.exports = router
student.js
// students.js 只关心数据,不关心业务
let fs = require('fs')
const path = './db.json'
// 读取所有数据
exports.find = function (callback) {
fs.readFile(path, 'utf8', function (err, data) {
if (err) {
return callback(err)
}
callback(null, JSON.parse(data).students)
})
}
// 根据id读取单个数据
exports.findOne = function (id, callback) {
fs.readFile(path, 'utf8', function (err, data) {
if (err) {
return callback(err)
}
let students = JSON.parse(data).students
let stu = students.find(function (item) {
return id === item.id
})
callback(null, stu)
})
}
// 增 添加保存学生 需要一个学生的student对象
exports.save = function (student, callback) {
fs.readFile(path, 'utf8', function (err, data) {
if (err) {
return callback(err)
}
let students = JSON.parse(data).students
let newId = students[students.length - 1]['id'] + 1
student.id = newId
students.push(student)
let stuObj = {'students': students}
let ret = JSON.stringify(stuObj)
//写入数据
fs.writeFile(path, ret, function (err) {
if (err) {
return callback(err)
}
callback(null)
})
})
}
// 改 更新学生
exports.update = function (student, callback) {
console.log(student)
fs.readFile(path, 'utf8', function (err, data) {
if (err) {
return callback(err)
}
let students = JSON.parse(data).students
console.log(students)
for (let i = 0; i < students.length - 1; i++) {
if (students[i].id === student.id) {
students[i] = student
}
}
let stuObj = {'students': students}
let ret = JSON.stringify(stuObj)
//写入数据
fs.writeFile(path, ret, function (err) {
if (err) {
return callback(err)
}
callback(null)
})
})
}
// 删 删除学生
exports.delete = function (id, callback) {
fs.readFile(path, 'utf8', function (err, data) {
if (err) {
return callback(err)
}
let num = ''
let students = JSON.parse(data).students
for (let i in students) {
if (students[i].id === id) {
num = i
}
}
students.splice(num, 1)
let stuObj = {'students': students}
let ret = JSON.stringify(stuObj)
fs.writeFile(path, ret, function (err) {
if (err) {
return callback(err)
}
callback(null)
})
})
}
index.html
<h2 class="sub-header">Section title</h2>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>爱好</th>
</tr>
</thead>
<tbody>
{{each students}}
<tr>
<td>{{$value.id}}</td>
<td>{{$value.name}}</td>
<td>{{$value.gender}}</td>
<td>{{$value.age}}</td>
<td>{{$value.hobbies}}</td>
<td>
<a href="/students/edit?id={{$value.id}}">编辑</a>
<a href="/students/delete?id={{$value.id}}">删除</a>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
new.html
<h2 class="sub-header">添加学生</h2>
<form action="/students/new" method="post">
<div class="form-group">
<label for="name">姓名</label>
<input type="text" class="form-control" id="name" name="name">
</div>
<div class="form-group">
<label>性别</label>
<div>
<label class="radio-inline">
<input type="radio" name="gender" id="man" value="0" checked> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="women" value="1"> 女
</label>
</div>
</div>
<div class="form-group">
<label for="age">年龄</label>
<input type="number" id="age" name="age" class="form-control">
</div>
<div class="form-group">
<label for="hobbies">爱好</label>
<input type="text" id="hobbies" class="form-control" name="hobbies">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
edit.html
<h2 class="sub-header">编辑学生</h2>
<form action="/students/edit" method="post">
<input type="hidden" value="{{student.id}}" name="id">
<div class="form-group">
<label for="name">姓名</label>
<input type="text" class="form-control" id="name" value="{{student.name}}" name="name">
</div>
<div class="form-group">
<label>性别</label>
<div>
<label class="radio-inline">
<input type="radio" name="gender" id="man" value="0" checked> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="women" value="1"> 女
</label>
</div>
</div>
<div class="form-group">
<label for="age">年龄</label>
<input type="number" id="age" name="age" class="form-control" value="{{student.age}}">
</div>
<div class="form-group">
<label for="hobbies">爱好</label>
<input type="text" id="hobbies" class="form-control" name="hobbies" value="{{student.hobbies}}">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
学到的一些知识点
//解析json文件
JSON.parse(data)
// 转为json文件
JSON.stringify(data)
exoress框架中,get请求中req.query获取路由参数,post请求没有获取参数的API,可以使用第三方模块body-parser的req.body方法获取参数
req.query.id和req.body.id获取到的id是字符串,需要通过parseInt(id)转换
在编辑页面时,此时post发送的student对象中没有id,可以通过发送一个隐藏的input数据得到id
<input type="hidden" value="{{student.id}}" name="id">
也学到了一些封装异步API的操作