curd-express步骤
1. 处理模板
2. 配置开放静态资源
npm init -y
npm i -S express
静态资源:css/image/js
3. 配置模板引擎(art-template)
安装:
npm install --save art-template
npm install --save express-art-template
配置:
// 第一个参数后缀名
app.engine('html',require('express-art-template'))
app.engine('art', require('express-art-template'))
使用:
app.get('/', function(req,res){
// express默认会去项目中的views目录找index.html
res.render('index.html',{
title: 'hello world'
})
})
修改默认的views目录:
app.set('views',render函数的默认目录)
4. 简单路由
4.1 /students渲染静态页面
public/css/main.css
4.2 在express获取表单get请求参数
express内置了一个API,可以直接通过req.query来获取
4.3 express获取表单post请求体数据
body-parse
安装:
npm install --save body-parse
配置:
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(function(req,res){
res.setHeader('Content-Type','text/plain')
res.write('you posted: \n')
res.end(JSON.stringify(req.body,null,2))
})
5. 路由设计
请求方法 | 请求路径 | get 参数 | post 参数 | 备注 |
---|---|---|---|---|
GET | /studens | 渲染首页 | ||
GET | /students/new | 渲染添加学生页面 | ||
POST | /studens/new | name、age、gender、hobbies | 处理添加学生请求 | |
GET | /students/edit | id | 渲染编辑页面 | |
POST | /studens/edit | id、name、age、gender、hobbies | 处理编辑请求 | |
GET | /students/delete | id | 处理删除请求 |
6. 提取路由模块
6.1 文件结构
router.js 路由模块
/**
* router.js 路由模块职责:
* 处理路由
* 根据不同的请求方法+请求路径设置具体的请求处理函数
* 模块职责要单一,不要乱写
* 我们划分模块的目的就是为了增强项目代码的可维护性,提升开发效率
*/
var fs = require('fs')
var Student = require('./student')
var express = require('express')
// 1.创建一个路由容器
var router = express.Router()
// 2.把路由都挂载到router路由容器中
router.get('/students',function(req,res){}) // 渲染学生列表页面
router.get('/students/new',function(req,res){}) // 渲染添加学生页面
router.post('/students/new',function(req,res){}) // 处理添加学生
router.get('/students/edit',function(req,res){}) // 渲染编辑学生页面
router.post('/students/edit',function(req,res){}) // 处理编辑学生
router.get('/students/delete',function(req,res){})// 处理删除学生
// 3.把router导出
module.exports = router
app.js
var router = require('./router')
app.use(router) // 挂载路由
student.js
设计操作数据的API文件模块
/**
* student.js 数据操作文件模块
* 职责:操作文件中的数据,只处理数据,不关心业务
* 封装异步 API
*/
exports.find = function(callback){} // 获取所有学生列表
exports.findById = function(id,callback){} // 根据 id 获取学生信息对象
exports.save = function(student,callback){} // 添加保存学生
exports.updateById = function(student,callback){}// 更新学生
exports.deleteById = function(id,callback){} // 删除学生
db.json
{
"students":[
{"id":1,"name":"张三2","gender":"1","age":"18","hobbies":"吃饭、睡觉、打豆豆"}, {"id":2,"name":"张三","gender":"0","age":"20","hobbies":"睡觉、打豆豆"},
{"name":"大家好","gender":"0","age":"34","hobbies":"吃","id":7}, {"name":"123","gender":"1","age":"22","hobbies":"睡觉、打豆豆","id":8}, {"name":"69","gender":"0","age":"55","hobbies":"吃","id":9}, {"name":"5555","gender":"0","age":"6","hobbies":"吃","id":10}
]
}
6.2 实现具体功能
-
通过路由收到请求
-
接收请求中的数据(get、post)
-
调用数据操作API处理数据
-
根据操作结果给客户端发送响应(新页面、重定向)
student.js
var dbPath = './db.json'
/*
获取所有学生列表
@param {Function} callback 回调函数
callback:
第一个参数是err: 成功是null,错误是错误对象
第二个参数是结果:成功是数组,错误是undefined
*/
exports.find = function(callback){
fs.readFile(dbPath,'utf8',function(err,data){
if(err){
return callback(err)
}
callback(null,JSON.parse(data).students)
})
}
/**
* 根据 id 获取学生信息对象
* @param {Number} id 学生 id
* @param {Function} callback 回调函数
*/
exports.findById = function(id,callback){
fs.readFile(dbPath,'utf8',function(err,data){
if(err){
return callback(err)
}
var students = JSON.parse(data).students
var ret = students.find(function(item){
return item.id === parseInt(id)
})
callback(null,ret)
})
}
/*
添加保存学生
* @param {Object} student 学生对象
* @param {Function} callback 回调函数
*/
exports.save = function(student,callback){
fs.readFile(dbPath,'utf8',function(err,data){
if(err){
return callback(err)
}
var students = JSON.parse(data).students
// 处理id唯一的,不重复
student.id = students[students.length-1].id + 1
// 把用户传递的对象保存到数组中
students.push(student)
// 把对象数据转成字符串,写到文件中
var fileData = JSON.stringify({
students:students
})
// 把字符串保存到文件中
fs.writeFile(dbPath,fileData,function(err){
if(err){
// 错误就是把错误对象传递给它
return callback(err)
}
// 成功就没错,所以错误对象就是null
callback(null)
})
})
}
// 更新学生
exports.updateById = function(student,callback){
fs.readFile(dbPath,'utf8',function(err,data){
if(err){
return callback(err)
}
var students = JSON.parse(data).students
// 把id统一转换为数字类型
student.id = parseInt(student.id)
// 需要修改谁就把谁找出来
// EcmaScript 6 中的一个数组方法:find,需要接收一个函数作为参数
// 当某个遍历项符合item.id === student.id条件的时候,find会终止遍历,同时返回遍历项
var stu = students.find(function(item){
return item.id === student.id
})
for(var key in student){
stu[key] = student[key]
}
var fileData = JSON.stringify({
students:students
})
// 把字符串保存到文件中
fs.writeFile(dbPath,fileData,function(err){
if(err){
// 错误就是把错误对象传递给它
return callback(err)
}
// 成功就没错,所以错误对象就是null
callback(null)
})
})
}
// 删除学生
exports.deleteById = function(id,callback){
fs.readFile(dbPath,'utf8',function(err,data){
if(err){
return callback(err)
}
var students = JSON.parse(data).students
// findIndex方法专门用来根据条件查找元素的下标
var deleteId = students.findIndex(function(item){
return item.id === parseInt(id)
})
// 根据下标从数组中删除对应的学生对象,第二个参数表示只删除一个
students.splice(deleteId,1)
// 再重新写入
var fileData = JSON.stringify({
students:students
})
// 把字符串保存到文件中
fs.writeFile(dbPath,fileData,function(err){
if(err){
return callback(err)
}
callback(null)
})
})
}
router.js
// 渲染添加学生页面
router.get('/students/new',function(req,res){
res.render('new.html')
})
// 处理添加学生
router.post('/students/new',function(req,res){
// 1.获取表单数据
// 2.处理: 将数据保存到db.json文件中用以持久化
// 3.发送响应
// 先读取出来,转成对象,然后往对象中push数据,然后把对象转为字符串,然后把字符串再次写入文件
Student.save(req.body,function(err){
if(err){
return res.status(500).send('Server error.')
}
// 没有问题就跳到首页
res.redirect('/students')
})
})
// 渲染编辑学生页面
router.get('/students/edit',function(req,res){
// 1.在客户端的列表页中处理链接问题(需要有id参数)
// 2.获取要编辑的学生id
// 3.渲染编辑页面
// 根据id把学生信息查出来
// 使用模板引擎渲染页面
Student.findById(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){
// 1.获取表单数据:req.body
// 2.更新:Student.updateById()
// 3.发送响应
Student.updateById(req.body,function(err){
if(err){
return res.status(500).send('Server error.')
}
res.redirect('/students')
})
})
// 处理删除学生
router.get('/students/delete',function(req,res){
// 1.获取要删除的id
// 2.根据id执行删除操作
// 3.根据操作结果发送响应数据
Student.deleteById(req.query.id,function(err){
if(err){
return res.status(500).send('Server error.')
}
res.redirect('/students')
})
})