七天搞定node.js---第四天

自学node.js第四天的笔记。

知识点

  • Express
  • 基于文件做一套 CRUD

模块标识中的 / 和文件操作路径中的 /

文件操作路径:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 在文件操作的相对路径中
// ./data/a.txt 相对于当前目录
// data/a.txt 相对于当前目录
// /data/a.txt 绝对路径,当前文件模块所处磁盘根目录
// c:/xx/xx... 绝对路径
// fs.readFile('/data/a.txt', function(err, data) {
// if (err) {
// // console.log(err)
// // Error: ENOENT: no such file or directory, open 'C:\data\a.txt'
// return console.log('读取失败')
// }
// console.log(data.toString())
// })

模块操作路径:

1
2
3
4
5
6
7
8

//这里如果忽略了 . 则也是去磁盘根目录找
require('/data/foo.js')

// 相对路径
require('./data/foo.js')

// 模块加载的路径中的相对路径不能省略 ./

Express

原生的 http 在某些方面表现不足以应对我们的开发需求,所以我们就需要使用框架来加快我们的开发效率,框架的目的就是提高效率,让我们的代码更高度统一。

在 Node 中,有很多 Web 开发框架,这里以 express 为主。

起步

安装:

1
npm install --save express

hello world

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var express = require('express')

//1.创建 app
var app = express()

app.get('/', function(req, res) {
// res.end('hello world')
res.send('you see see one day day')
})

app.get('/login', function(req, res) {
// res.end('hello world')
res.send('login page')
})

app.listen(3000, function() {
console.log('express app is running ~')
})

基本路由

GET:

1
2
3
app.get('/',function(req,res){
res.send('Hello World~')
})

POST:

1
2
3
app.post('/',function(req,res){
res.send('Got a POST request~')
})

静态服务

1
2
3
4
5
6
7
8
9
10
11
// public里面的具体资源
app.use(express.static('public'))
// files里面的具体资源
app.use(express.static('files'))

// /public/public里面的具体资源
app.use('/public/',express.static('public'))
// /static/public里面的具体资源
app.use('/static/',express.static('public'))

app.use('/static/',express.static(path.join(__dirname,'public')))

在 Express 中配置使用 art-templat模板引擎

安装

1
2
npm install --save art-template
npm install --save express-art-template

配置

1
app.engine('art', require('express-art-template'));

使用

1
2
3
4
5
6
app.get('/',function(req,res){
// express 默认会去项目中的 views 目录中找 index.html
res.render('index.html',{
title:'hello world~'
})
})

修改默认的 views 视图渲染存储目录:

1
app.set('views','render函数的默认路径')

在 Express 中获取表单 GET 请求参数

express 内置了一个 API ,可以直接通过 req.query来获取

1
req.query

在 Express 获取表单 POST 请求体数据

在 Express 中没有内置获取表单 POST 请求体的 API ,需要使用一个第三方包:body-parser

安装

1
npm install body-parser

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var express = require('express')
// 0.引包
var bodyParser = require('body-parser')

var app = express()

// 配置 body-parser
// 只要加入这个配置,则在 req 请求对象上会多出来一个属性:body
// 也就是说可以直接通过 req.body 来获取表单 POST 请求体数据了
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

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

使用

1
2
3
4
5
6
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
// 通过 req.body 来获取表单 POST 请求体数据了
res.end(JSON.stringify(req.body, null, 2))
})

修改完代码自动重启服务器

使用第三方命令行工具:nodemon来解决频繁修改代码手动重启服务器问题
nodemon 是一个基于 Node.js开发的一个第三方命令行工具,在使用的时候需要独立安装:

1
2
3
// 在任意目录执行都行
// 也就是说,所有需要 --global 来安装的包都可以在任意目录执行
npm install --global nodemon

安装完毕之后,使用:

1
2
3
4
5
//以前
node app.js

//使用nodemon
nodemon app.js

只要通过nodemon app.js启动的服务,则它会监事你的文件变化,当文件发生变化的时候,自动帮你重启服务器。

基于文件完成CRUD(增删改查),在bootstarp官网偷的一套模板~

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<!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>Dashboard Template for Bootstrap</title>

<!-- Bootstrap core CSS -->
<link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">

<!-- Custom styles for this template -->
<link href="/public/css/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="#">Overview <span class="sr-only">(current)</span></a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item</a></li>
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
<li><a href="">More navigation</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header">Dashboard</h1>

<div class="row placeholders">
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
<div class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-muted">Something else</span>
</div>
</div>

<h2 class="sub-header">Section title</h2>
<a href="/students/news" 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>{{$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>
</div>
</div>
</div>
</body>

</html>

news.html页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<!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>Dashboard Template for Bootstrap</title>

<!-- Bootstrap core CSS -->
<link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">

<!-- Custom styles for this template -->
<link href="/public/css/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="#">Overview <span class="sr-only">(current)</span></a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item</a></li>
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
<li><a href="">More navigation</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h2 class="sub-header">添加学生</h2>
<form action="/students/news" method="POST">
<div class="form-group">
<label for="">姓名:</label>
<input type="text" class="form-control" id="" placeholder="name" name="name">
</div>
<div class="form-group">
<label for="">性别:</label>
<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 class="form-group">
<label for="">年龄:</label>
<input type="number" id="" name="age" class="form-control" placeholder=" age">
</div>
<div class="form-group ">
<label for=" ">爱好:</label>
<input type="text " id=" " name="hobbies" class="form-control " placeholder="hobbies ">

</div>
<button type="submit " class="btn btn-default ">添加</button>
</form>
</div>
</div>
</div>
</body>

</html>

edit.html页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<!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>Dashboard Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="/public/css/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="/students">学生管理 <span class="sr-only">(current)</span></a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item</a></li>
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
<li><a href="">More navigation</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item again</a></li>
<li><a href="">One more nav</a></li>
<li><a href="">Another nav item</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h2 class="sub-header">编辑学生</h2>
<form action="/students/edit" method="post">
<!--
用来放一些不希望被用户看见,但是需要被提交到服务端的数据
-->
<input type="hidden" name="id" value="{{ student.id }}">
<div class="form-group">
<label for="">姓名</label>
<input type="text" class="form-control" id="" name="name" required minlength="2" maxlength="10" value="{{ student.name }}">
</div>
<div class="form-group">
<label for="">性别</label>
<div>
<label class="radio-inline">
<input type="radio" name="gender" id="" value="0" checked> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="" value="1"> 女
</label>
</div>
</div>
<div class="form-group">
<label for="">年龄</label>
<input class="form-control" type="number" id="" name="age" value="{{ student.age }}" required min="1" max="150">
</div>
<div class="form-group">
<label for="">爱好</label>
<input class="form-control" type="text" id="" name="hobbies" value="{{ student.hobbies }}">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
</body>

</html>

提取出来的路由模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
* router.js 路由模块
* 职责:
* 处理路由
* 根据不同的请求方法+请求路径设置具体的请求处理函数
* 模块职责要单一,不要乱写
* 我们划分模块的目的就是为了增强项目代码的可维护性
* 提升开发效率
*/

var fs = require('fs')
var Student = require('./students')

// Express 提供了一种更好的方式
// 专门用来包装路由的
var express = require('express')

// 1. 创建一个路由容器
var router = express.Router()

// 2. 把路由都挂载到 router 路由容器中

/*
* 渲染学生列表页面
*/
router.get('/students', function(req, res) {
Student.find(function(err, students) {
if (err) {
return res.status(500).send('Server error.')
}
res.render('index.html', {
students: students
})
})
})

/*
* 渲染添加学生页面
*/
router.get('/students/new', function(req, res) {
res.render('new.html')
})

/*
* 处理添加学生
*/
router.post('/students/new', function(req, res) {
// 1. 获取表单数据
// 2. 处理
// 将数据保存到 db.json 文件中用以持久化
// 3. 发送响应
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')
})
})

// 3. 把 router 导出
module.exports = router

封装的数据操作文件模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
* student.js
* 数据操作文件模块
* 职责:操作文件中的数据,只处理数据,不关心业务
*
* 这里才是我们学习 Node 的精华部分:奥义之所在
* 封装异步 API
*/

var fs = require('fs')

var dbPath = './db.json'

/**
* 获取学生列表
* @param {Function} callback 回调函数
*/
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
})

// 这种方式你就写死了,有 100 个难道就写 100 次吗?
// stu.name = student.name
// stu.age = student.age

// 遍历拷贝对象
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)
})
})
}

入口文件 app.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var express = require('express')
var router = require('./router')
var bodyParser = require('body-parser')

var app = express()
app.engine('html', require('express-art-template'))
app.use('/node_modules/', express.static('./node_modules'))
app.use('/public/', express.static('./public'))
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

app.use(router)


app.listen(3000, function() {
console.log('running')
})

数据库文件 db.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"students": [{
"id": 3,
"name": "木槿",
"gender": 0,
"age": "19",
"hobbies": "读书,学习,敲代码"
}, {
"id": 4,
"name": "木槿",
"gender": 0,
"age": 18,
"hobbies": "读书,学习,敲代码"
}, {
"id": 5,
"name": "木槿",
"gender": 0,
"age": 18,
"hobbies": "读书,学习,敲代码"
}, {
"name": "莫子谦",
"gender": "1",
"age": "19",
"hobbies": "唱、跳、rap",
"id": 15
}]
}

源代码可以去我的 github 克隆

-------------本文结束感谢您的阅读-------------
木槿前端不求人,有空就来坐坐。
0%