这里使用express框架,搭建起来简单,不用从底层做起,node是javascript运行时环境,实质是对chrome V8引擎进行了封装.node.js是一个让javascript运行在服务端的开发平台,它让javascript成为与php,python的服务端语言平起平坐的脚本语言。
node.js能开发像apach,tomcat等还可以开发npm包管理工具
我做的这个实现了基本的增删改查功能,使用bootstrap快速搭建网站,使用express-art-template渲染网页。很多都是对url路径已经表单提交的操作。链接的是mongdb数据库(非线性数据库)。
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>Student Management System
</title>
<!-- Bootstrap core CSS -->
<link href='/node_modules/bootstrap/dist/css/bootstrap.min.css' rel="stylesheet">
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<link href="../../assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="/public/dashboard.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<script src="../../assets/js/ie-emulation-modes-warning.js"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header">node.js之学生管理系统</h1>
</div>
<h2 class="sub-header">By LiuJinPeng</h2>
<a href="/students/new" class="btn btn-success">添加按钮</a>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>爱好</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{{ each students }}
<tr>
<td>{{ $index +1}}</td>
<td>{{ $value.name }}</td>
<td>{{ $value.gender }}</td>
<td>{{ $value.age }}</td>
<td>{{ $value.habbit }}</td>
<td><a href="/students/edit?id={{ $value.id }}">编辑</a><a href="/students/delete?id={{ $value.id }}">删除</a></td>
</tr>
{{ /each}}
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="../../assets/js/vendor/holder.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../assets/js/ie10-viewport-bug-workaround.js"></script>
</body>
</html>
new.html
<!DOCTYPE html>
<html>
<head>
<title>添加学生</title>
<link href='/node_modules/bootstrap/dist/css/bootstrap.min.css' rel="stylesheet">
</head>
<body>
<form action="/students/new" method="post">
<h2>添加学生</h2>
<div>
<div>
<label>name</label>
<input type="text" class="form-control" name="name">
</div>
<div>
<label class="radio-inline">
<input type="radio" name="gender" id="" value="0"> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="" value="1"> 女
</label>
</div>
<div>
<label>年龄</label>
<input class="form-control" type="number" name="age">
</div>
<div>
<label>爱好</label>
<input class="form-control" type="text" name="habbit">
</div>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</body>
</html>
app.js 运行的js文件
const express=require('express')
const fs=require('fs')
const bodyParser=require('body-parser')
const app=express()
var router=require('./router')
app.engine('html',require('express-art-template'))
app.use('/public/',express.static('./public'))
app.use('/node_modules',express.static('./node_modules'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
// app.engine('html',require('express-art-template'))
// app.get('/',(req,res) =>{
// fs.readFile('/db.json','utf-8',(error,data) =>{
// if(error){
// return res.status(500).send('server error')
// }
// console.log(data)
// }),
// // res.render('index.html',)
// })
app.use(router)
app.listen(3000, () =>{
console.log('runing...')
})
router.js 路由文件
// 路由模块
const Students=require('./students-mongdba')
const fs=require('fs')
const express=require('express')
//创建一个路由容器
const router=express.Router()
router.get('/students',(req,res) =>{
Students.find(function(err,students){
if(err){
return res.status(500).send('Server error')
}
res.render('index.html',{
students:students
})
})
})
router.get('/students/new',(req,res) =>{
res.render('new.html')
})
//处理post添加学生
// res.render('new.html')
// fs.readFilr('/db.json','utf-8',(error,data) =>{
// })
router.post('/students/new',(req,res)=>{
new Students(req.body).save(err =>{
if(err){
return res.send(err)
}
res.redirect('/students')
})
})
// Students.save(req.body, err =>{
// if(err){
// return res.send(err)
// }
// res.redirect('/students')
// })
// })
router.get('/students/edit',(req,res) =>{//get参数 这是
Students.findById(req.query.id,function(err,result){
if(err){
return res.status(500),send('Server err')
}
res.render('edit.html',{
student:result
})
})
})
router.post('/students/edit',(req,res) =>{
// console.log(req.body)
Students.findByIdAndUpdate(req.body.id,req.body,function(err){//第一个参数是id 第二个参数是需要修改的数据
if(err){
return res.status(500),send('Server err')
}
res.redirect('/students')
})
})
//删除
router.get('/students/delete',(req,res) =>{
console.log(req.query)
Students.findByIdAndDelete(req.query.id,function(err){
if(err){
res.status(500).send('Server error')
}
res.redirect('/students')
})
})
module.exports=router
students-mongdb.js 配置mongdb数据库文件
var mongoose = require('mongoose')
var Schema = mongoose.Schema
// var mongo=require('mongodb').MongoClient;
mongoose.connect('mongodb://localhost/itcast')
var commentSchema = new Schema({
name:{
type:String,
required:true
},
gender:{
type:Number,
// required:true,
enum:[0,1],//枚举0 或者1
default:0// 默认值
},
age:{
type:Number,
required:true
},
habbit:{
type:String,
// required:true
}
})
//构造model
module.exports=mongoose.model('Students',commentSchema)
student.js 业务实现文件
var fs = require('fs')
var dbPath = './db.json'
// var mongoose = require('mongoose')
// var Schema = mongoose.Schema
// var commentSchema = new Schema({
// })
// //构造model
// module.exports=mongoose.model('Comment',commentSchema)
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 ,唯一不重复
if(students.length<=0){
student.id=1
}else {
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)
}
// 成功就没错,所以错误对象是 null
callback(null)
})
})
}