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
* 数据操作文件模块
* 职责:操作文件中的数据,只处理数据,不关心业务
*
* 这里才是我们学习 Node 的精华部分:奥义之所在
* 封装异步 API
*/
/*
获取所有学生列表
*/
exports.find = function(callback){
}
/**
* 根据 id 获取学生信息对象
*/
exports.findById = function(id,callback){
}
/*
添加保存学生
*/
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.发送响应
// console.log(req.body)
//先读取出来,转成对象,然后往对象中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.')
}
//console.log(student)
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')
})
})