带你学Node系列之express-CRUD
前言
hello,小伙伴们,我是你们的pubdreamcc
,本篇博文出至于我的GitHub仓库node学习教程资料
,欢迎小伙伴们点赞和star
,你们的点赞是我持续更新的动力。
GitHub仓库地址:node学习教程
本篇文章对应的源码:Student-Management-System
好了,废话不多说了,今天继续我们express
的学习~
Student-Management-System
今天我们实现一个案例,用express实现基本的C-R-U-D(增删改查)学生信息管理系统。学习这个案例一方面让我们熟悉业务开发的流程,一方面可以巩固之前学习的express知识。
文件说明
app.js -- 入口模块
router.js -- 路由模块
student.js -- 操作数据模块(封装操作数据的基本API)
Db.json -- 模拟数据库,保存数据的文件
views文件夹 -- 页面视图文件
public文件夹 -- 静态资源文件
启动
git clone
克隆项目到本地npm install
进入项目文件夹,下载相关依赖node app.js
node启动项目
主体设计
- 创建
public
静态文件夹,views
页面视图文件夹。
项目中前端页面使用了bootstrap
快速搭建,所有需要开放bootstrap样式文件和页面相关的脚本文件。在views
文件夹中存放主页面: index.html
,编辑学生信息页面:edit.html
,添加学生页面:add.html
。
- 创建数据文件
Db.json
,模拟数据库存放学生信息数据
因为我们没有涉及到数据库,所以暂时把学生数据存放在Db.json文件中,在数据文件中,我们需要一个数组:students
,用来存放每一个学生的信息。通常数据文件都是一个json格式文件,所以严格按照json格式要求来模拟数据。
{
"students": [
{
"id": 1,
"name": "牛魔王",
"age": 18,
"hobbies": "打人"
}
...
]
}
- 创建入口模块:app.js
在入口模块中启动服务器,配置art-template
模板引擎,配置express中间件body-parser
解析post
请求提交的数据,最后把路由容器router
挂载到app服务器实例上。因为node中解析代码是从上至下,所以路由容器挂载必须在各项配置之后,否则会出错。
const express = require('express')
const router = require('./router')
const bodyParser = require('body-parser')
const app = express()
// 开发静态资源
app.use('/public/', express.static('./public'))
app.use('/node_modules/', express.static('./node_modules'))
// 配置模板引擎
app.engine('html', require('express-art-template'))
// 配置body-parser,得到post请求体数据
app.use(bodyParser.urlencoded({ extended: false }))
// 注意:配置模板引擎和body-parser,开放静态资源必须放在路由容器挂载之前
// 挂载路由容器
app.use(router)
// 绑定端口号,开启服务
app.listen(3000, () => {
console.log('running...')
})
- 抽取路由模块
router.js
,专门处理每个路由
因为项目中需要处理多个路由,所以我们分离出一个路由模块,用来处理路由信息。模块的分离使得node中每个模块各司其职,职能单一,同时也便于后期代码维护。
router.js
模块中每个路由都需要涉及到操作数据文件,所以我们在此之外需要封装一些数据操作的API。封装异步 API这里才是我们学习 Node 的精华部分:奥义之所在。
// 路由模块
const express = require('express')
const Student = require('./student')
// 得到路由容器
const router = express.Router()
/*
* 下面就是把每条路由都挂载到路由容器中
*/
// 请求'/',显示全部学生信息
router.get('/', (req, res) => {
// 调用Student.find()API,获取所有学生信息
。。。
})
// 请求/add',显示添加学生信息的界面
router.get('/add', (req, res) => {
res.render('add.html')
})
// 表单post提交数据到'/add',处理数据后重定向至'/'
router.post('/add', (req, res) => {
/*
*获取表单提交的数据
*添加到数据文件中
*重定向至首页,显示新提交的学生信息
*/
。。。
})
// 请求'/edit',展示编辑学生信息界面
router.get('/edit', (req, res) => {
// 调用 Student.findById()API,通过id值获取学生信息渲染在页面上
。。。
})
// 获取post请求提交的数据,更新学生信息,重定向到'/'
router.post('/edit', (req, res) => {
/**
* 获取新修改的post请求提交的学生信息
* 处理数据文件,修改学生信息
* 重定向到'/'
*/
})
// 当请求'/delete',根据id值删除相应的学生信息,重定向到'/'
router.get('/delete', (req, res) => {
// 调用 Student.deleteById()API,通过id值查找到对应学生,删除其信息
。。。
})
module.exports = router
- 封装数据操作的API,提取数据操作文件模块
student.js
数据操作的模块,只负责操作数据(增加新数据,修改数据,删除数据等),不关心业务逻辑。
注意:我们在操作数据文件的时候,永远只能是:先读取出来原有的字符串数据,转换成对象,处理完成之后,再把对象转换成JSON格式字符串,最后再保存到数据文件中。文件中永远存放的是字符串格式的数据。
由于是这种操作顺序,所以student.js中频繁使用到node核心模块fs
,反复调用fs.readFile()
读取文件内容,fs.writeFile()
修改文件中的数据。
// 引入fs核心模块
const fs = require('fs')
// 保存学生信息
/**
* 保存新添加的学生信息到数据文件中
* 参数:
* 1. 新加的学生信息对象
* 2. callback回调函数,拿到异步操作的结果
* callback中的参数:
* 第一个参数err
* 成功是null, 失败是错误对象
* 第二个参数是结果
* 成功是数组,失败是undefined
*/
exports.save = (student, callback) => {
fs.readFile('./Db.json', 'utf8', (err, data) => {
if (err) {
return callback(err)
}
// 得到所有学生信息
let students = JSON.parse(data).students
// 为新加的学生添加一个唯一的id属性(原来最大id属性值基础上加1)
if (students.length === 0) {
// 如果原始数据文件中没有学生信息
student.id = 1
} else {
student.id = parseInt(students[students.length-1].id) + 1
}
students.push(student)
// 把新增加学生信息后的对象转换成字符串保存到数据文件中
let dataStr = JSON.stringify({
students: students
})
fs.writeFile('./Db.json', dataStr, err => {
if (err) {
// 如果写入失败,则把错误对象传递给它
return callback(err)
}
// 成功就没错,所以错误对象是 null
callback(null)
})
})
}
。。。
由于篇幅原因,这里只罗列了添加学生信息API的实现代码。这里还有一个非常重要的知识点:怎样获取到一个函数内部异步操作的结果?
只能是通过回调函数。
或许有一些其他的内置模块,包括封装的API也可以拿到异步操作的结果,但是其底层都是利用了回调函数的思想。比如常见的Node内置events
事件模块等。
- 视图文件编写
这里只需强调一点,在编写视图文件的时候,需要把一些动态的数据用模板语法包裹起来,能够使得模板引擎正确的渲染模板文件即可。
- 启动服务后看结果(略)
后话
需要学习资料和案例源码的伙伴可以去GitHub上查看,如果您对这案例或者学习资料有更好的看法,欢迎issue,或者评论,谢谢。
带你学Node系列之express-CRUD的更多相关文章
- 从零开始学node(一): nodejs开发环境的配置
从零开始学node系列(一): nodejs环境安装 一.安装node.js 1. node官网,node安装十分方便快捷,所以这一步还是很顺利的. 2. webstorm是一款强大的前端开发IDE, ...
- 打算写一个《重学Node.js》系列,希望大家多多支持
先放上链接吧,项目已经开始2周了:https://github.com/hellozhangran/happy-egg-server 想法 现在是2019年11月24日,还有人要开始学习Node.js ...
- 每天几分钟跟小猫学前端之node系列:用node实现最简单的爬虫
先来段求分小视频: https://www.iesdouyin.com/share/video/6550631947750608142/?region=CN&mid=6550632036246 ...
- 深入理解Node系列-细说Connect(上)
前言 想必对于广大前后端的同学们,Node 或是用来作为网站服务器的搭建,亦或是用来作为开发脚手架的运用,或是早有套路,亦或是浅尝辄止.从现在开始博主将会不定时的对 Node 系列的产品做分析,其中夹 ...
- 如何设计一个基于Node.js和Express的网站架构?
前言 今年七月份,我和几个小伙伴们合伙建立了一个开发团队.业务开展如火如荼的同时,团队宣传就提上了日程,所以迫切需要搭建公司网站出来.确定目标后我们就开始考虑如果构建一个企业网站.先是进行业内调查,看 ...
- Node.js、express、mongodb 实现分页查询、条件搜索
前言 在上一篇Node.js.express.mongodb 入门(基于easyui datagrid增删改查) 的基础上实现了分页查询.带条件搜索. 实现效果 1.列表第一页. 2.列表第二页 3. ...
- Node.js、express、mongodb 入门(基于easyui datagrid增删改查)
前言 从在本机(win8.1)环境安装相关环境到做完这个demo大概不到两周时间,刚开始只是在本机安装环境并没有敲个Demo,从周末开始断断续续的想写一个,按照惯性思维就写一个增删改查吧,一方面是体验 ...
- .net基础学java系列(二)IDE
上一篇文章.net基础学java系列(一)视野 废话: "视野"这篇文章,管理员说它比较空洞!也许初学者看不懂表格中的大部分内容!多年的neter估计也有很多不知道的! 有.net ...
- 2-STM32带你入坑系列(点亮一个灯--Keil)
1-STM32带你入坑系列(STM32介绍) 首先是安装软件 这一节用Kei来实现,需要安装MDK4.7这个软件,怎么安装,自己百度哈.都学习32的人了,不会连个软件都不会安装吧....还是那句话 没 ...
随机推荐
- fossil 代理设置
C:\>fossil user new Joe C:\>fossil user default Joe 设置账户 fossil setting proxy http://-:-fossil ...
- Ueditor1.4.3上传视频IE下无法播放的问题
一:百度编辑器插入视频后,自动生成一段代码: <video class="edui-upload-video vjs-default-skin video-js" contr ...
- 分布式mysql 和 zk ( zookeeper )的分布式的区别 含冷热数据讨论
zk ( zookeeper )的分布式仅仅指的是备份模式. 分布式 mysql 不仅仅要关注备份(从以往的半主,主主,到 paxos). (mysql 比 hbase 的region成熟, hdfs ...
- ios UITableViewCell重用问题
在写sina 微博界面的过程中使用到了cell,那么就是在cell上添加一些控件,但是由于每条微博的内容都是不同的,所以在显示的过程中,出现了内容重叠的问题,其实就是UITableViewCell重用 ...
- 初涉树形dp
算是一个……复习以及进阶? 什么是树形dp 树形dp是一种奇妙的dp…… 它的一个重要拓展是和各种树形的数据结构结合,比如说在trie上.自动机上的dp. 而且有些时候还可以拓展到环加外向树.仙人掌上 ...
- 蓝牙学习(5) -- sockets
Frames 由下图可以看出 - SDU由多个I-frames中的Information Payload组成 - 一个I-frames又拆分成多个HCI data payload socket buf ...
- vue源码构建代码分析
这是xue源码学习记录,如有错误请指出,谢谢!相互学习相互进步. vue源码目录为 vue ├── src #vue源码 ├── flow #flow定义的数据类型库(vue通过flow来检测数据类型 ...
- 三段式fsm
1.状态转移的always中CS,同步ouput的always中NS. 2.3段fsm vs 2段fsm:output逻辑是组合逻辑和同步时序逻辑(消除里不稳的和毛刺). 3.3段fsm vs 1段f ...
- centos 7.3 快速安装ceph
Ceph的部署手册(Centos7.3) Ceph简介 Ceph是一种为优秀的性能.可靠性和可扩展性而设计的统一的.分布式文件系统. 部署逻辑架构 准备3台主机,并且修改主机名(hostnam ...
- LeetCode(114) Flatten Binary Tree to Linked List
题目 分析 按要求转换二叉树: 分析转换要求,发现,新的二叉树是按照原二叉树的先序遍历结果构造的单支二叉树(只有右子树). 发现规则,便容易处理了.得到先序遍历,构造即可. AC代码 /** * De ...