Node.js基于Express简单实战

路由设计

请求方式

url

备注

GET

/students

获取所有学生

POST

/students/addStu

添加学生

POST

/students/editStu

编辑学生

GET

/students/getStuById

根据ID查找学生

GET

/students/option

学生管理操作

GET

/students/delStu

删除学生

目录结构

Node.js基于Express简单实战

​​​​​​​//views文件存储视图页面
//db.json用于持久化操作,用文件流操作,暂不使用数据库
//app.js主入口,启动服务器等
//route.js存放路由
//student.js 做增删改查处理数据

安装依赖包

//Express框架依赖
npm i express --save
npm i express-art-template --save
//模板引擎
npm i art-template --save
//Express框架用于解析请求体参数的依赖
npm i body-parser --save

文件详情

app.js

​​​​​​​const express = require('express');
const app = express();
var router = require('./route.js');
var bodyParser = require('body-parser')
//配置模板引擎
app.engine('html', require('express-art-template'));
app.set('view engine', 'html');


//配置接受post请求参数的中间件
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
	extended: false
}))

// parse application/json
app.use(bodyParser.json())

app.use(router);

app.listen(3000, () => {
	console.log('server is runnging and listen to 3000 port');
});

db.json

{
	"students": [{
		"id": 1,
		"name": "zws",
		"number": "13332111",
		"gender": "1"
	}]
}

route.js

const express = require('express');
let student = require('./student.js');
let router = express.Router();
//首页
router.get('/students', (req, res) => {
	student.find((error, data) => {
		if (error) {
			return res.status(500).send('服务器错误');
		}
		res.render('index.html', {
			students: data
		});
	});
});
//管理学生操作
router.get('/students/option', (req, res) => {
	//如果有传id则是修改否则是增加
	if (req.query.id) {
		student.findStuById(req.query.id, (err, data) => {
			if (err) {
				return res.status(500).send('服务器错误');
			}
			res.render('option.html', {
				returnUrl: '/students/editStu',
				students: data
			});
		});
		return;
	}
	return res.render('option.html', {
		returnUrl: '/students/addStu',
		students: {}
	});

});
//添加学生
router.post('/students/addStu', (req, res) => {
	student.addStu(req.body, (err) => {
		if (err) {
			return res.status(500).send('服务器错误');
		}
		res.redirect('/students');
	});
});

//修改学生
router.post('/students/editStu', (req, res) => {
	student.editStu(req.body, (err) => {
		if (err) {
			return res.status(500).send('服务器错误');
		}
		res.redirect('/students');
	})
});
//删除学生
router.get('/students/delStu', (req, res) => {
	student.delStu(req.query.id, (err) => {
		if (err) {
			return res.status(500).send('服务器错误');
		}
		res.redirect('/students');
	});

});

module.exports = router;

student.js

const fs = require('fs');

//查找所有学生
module.exports.find = (callback) => {
	fs.readFile('./db.json', (error, data) => {
		if (error) {
			callback(error);
		}
		let students = JSON.parse(data.toString()).students;
		callback(null, students);
	});
};

//添加学生
module.exports.addStu = (student, callback) => {
	fs.readFile('./db.json', (error, data) => {
		if (error) {
			return callback(error);
		}
		let students = JSON.parse(data.toString()).students;
		//不做的太细节,id只做简单处理
		student.id = students.length + 1;
		students.push(student);
		//保存到json文件
		fs.writeFile('./db.json', JSON.stringify({
			students: students
		}), (err) => {
			callback(err);
		});
	});
};

//修改学生
module.exports.editStu = (student, callback) => {
	fs.readFile('./db.json', (error, data) => {
		if (error) {
			return callback(error);
		}
		let students = JSON.parse(data.toString()).students;
		let stu;
		students.map((data, index) => {
			if (parseInt(student.id) === data.id) {
				stu = data;
			}
		});
		for (let key in student) {
			stu[key] = student[key];
		}
		//转化成整型变量
		stu.id = parseInt(stu.id);
		//保存到json文件
		fs.writeFile('./db.json', JSON.stringify({
			students: students
		}), (err) => {
			callback(err);
		});
	});
};

//根据ID查找学生
module.exports.findStuById = (id, callback) => {
	fs.readFile('./db.json', (error, data) => {
		if (error) {
			return callback(error);
		}
		let students = JSON.parse(data.toString()).students;
		students.map((data, index) => {
			if (parseInt(id) === data.id) {
				callback(null, data);
			}
		});
	});
};

//删除学生
module.exports.delStu = (id, callback) => {
	fs.readFile('./db.json', (error, data) => {
		if (error) {
			return callback(error);
		}
		let students = JSON.parse(data.toString()).students;
		students.map((data, index) => {
			if (parseInt(id) === data.id) {
				students.splice(index, 1);
			}
		});
		//保存到json文件
		fs.writeFile('./db.json', JSON.stringify({
			students: students
		}), (err) => {
			callback(err);
		});
	});
};

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">
		<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
		<meta name="description" content="">
		<meta name="author" content="">
		<link rel="icon" href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/favicon.ico">
		<link rel="canonical" href="https://getbootstrap.com/docs/3.4/examples/dashboard/">

		<title>Dashboard Template for Bootstrap</title>

		<!-- Bootstrap core CSS -->
		<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/dist/css/bootstrap.min.css"
			rel="stylesheet">
		<!-- Custom styles for this template -->
		<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/examples/dashboard/dashboard.css"
			rel="stylesheet">
	</head>

	<body>

		<nav class="navbar navbar-inverse navbar-fixed-top">
			<div class="container-fluid">
				<div class="navbar-header">
					<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
						aria-expanded="false" aria-controls="navbar">
						<span class="sr-only">Toggle navigation</span>
						<span class="icon-bar"></span>
						<span class="icon-bar"></span>
						<span class="icon-bar"></span>
					</button>
					<a class="navbar-brand" href="#">Project name</a>
				</div>
				<div id="navbar" class="navbar-collapse collapse">
					<ul class="nav navbar-nav navbar-right">
						<li><a href="#">Dashboard</a></li>
						<li><a href="#">Settings</a></li>
						<li><a href="#">Profile</a></li>
						<li><a href="#">Help</a></li>
					</ul>
					<form class="navbar-form navbar-right">
						<input type="text" class="form-control" placeholder="Search...">
					</form>
				</div>
			</div>
		</nav>

		<div class="container-fluid">
			<div class="row">
				<div class="col-sm-3 col-md-2 sidebar">
					<ul class="nav nav-sidebar">
						<li class="active"><a href="#">student <span class="sr-only">(current)</span></a></li>
					</ul>
				</div>
				<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
					<button type="button" onclick="location.href='/students/option'" class="btn btn-success">添加</button>
					<h2 class="sub-header">Section title</h2>
					<div class="table-responsive">
						<table class="table table-striped">
							<thead>
								<tr>
									<th>id</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.number}}</td>
									<td><button type="button"
											onclick="location.href='/students/option?id='+{{$value.id}}"
											class="btn btn-primary">修改</button>
										<button type="button"
											onclick="location.href='/students/delStu?id='+{{$value.id}}"
											class="btn btn-danger">删除</button>
									</td>
								</tr>
								{{/each}}
							</tbody>
						</table>
					</div>
				</div>
			</div>
		</div>
	</body>
</html>

option.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">
		<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
		<meta name="description" content="">
		<meta name="author" content="">
		<link rel="icon" href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/favicon.ico">
		<link rel="canonical" href="https://getbootstrap.com/docs/3.4/examples/dashboard/">

		<title>Dashboard Template for Bootstrap</title>

		<!-- Bootstrap core CSS -->
		<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/dist/css/bootstrap.min.css"
			rel="stylesheet">
		<!-- Custom styles for this template -->
		<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.10/examples/dashboard/dashboard.css"
			rel="stylesheet">
	</head>

	<body>
		<div class="container">
			<div class="row">
				<div class="col-md-8 col-md-offset-2">
					<form action="{{returnUrl}}" method="post">
						<div class="form-group" style="display: none;">
							<label for="exampleInputEmail1">id</label>
							<input type="text" name="id" value="{{students.id}}" class="form-control" placeholder="Email">
						</div>
						<div class="form-group">
							<label for="name">name</label>
							<input type="text" class="form-control" name="name" value="{{students.name}}" id="name" placeholder="name">
						</div>
						<div class="form-group">
							<label for="number">number</label>
							<input type="text" value="{{students.number}}" name="number" class="form-control" id="number" placeholder="number">
						</div>
						<div class="form-group">
							<label class="radio-inline">
								<input type="radio" name="gender" id="inlineRadio1" value="1"> 男
							</label>
							<label class="radio-inline">
								<input type="radio" name="gender" id="inlineRadio2" value="2"> 女
							</label>
						</div>
						<button type="submit" class="btn btn-default">Submit</button>
					</form>
				</div>
			</div>
		</div>
	</body>
</html>

 

上一篇:[PHP] Ubuntu 16.10 开启PHP错误提示


下一篇:java_反射_及其简单应用(2016-11-16)