nodejs crud案例 json文件取数据

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>学生列表</title>

    <!-- Bootstrap core CSS -->
    <!-- <link href="/node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet"> -->
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="/public/css/main.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]-->
  </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">
          {{ each fruits }}
            <div class="col-xs-6 col-sm-3 placeholder">
              <img src="https://img-blog.csdnimg.cn/2022010614075843631.gif" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
              <h4>Label</h4>
              <span class="text-muted">{{ $value }}</span>
            </div>
           {{/each}}
          </div>

          <h2 class="sub-header">Section title</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>{{ $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 }}" class="btn btn-success">编辑</a>
                    <a href="/students/delete?id={{ $value.id }}" class="btn btn-danger">删除</a>
                  </td>
                </tr>
                {{ /each }}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>

 edit.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>添加学生</title>

    <!-- Bootstrap core CSS -->
    <!-- <link href="/node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet"> -->
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="/public/css/main.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]-->
  </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/edit" method="post">
            <div class="form-group">
              <label for="name">姓名</label>
              <input type="text" class="form-control" id="name" placeholder="姓名" name="name" value="{{ student.name }}">
              <!-- 隐藏元素用来存放不希望被用户看见,但必须得提交的内容 -->
              <input type="hidden" name="id" value="{{ student.id }}">
            </div>
            <div class="form-group">
              <label >性别</label>
              <div>
                <label class="radio-inline">
                <input type="radio" name="gender" id="gender" value="0"> 男
                </label>
                <label class="radio-inline">
                <input type="radio" name="gender" id="gender" value="1"> 女
                </label>
              </div>
            </div>
            <div class="form-group">
              <label for="age">年龄</label>
              <input type="number" class="form-control" id="age" placeholder="年龄" name="age" value="{{ student.age }}">
            </div>
            <div class="form-group">
              <label for="hobbies">爱好</label>
              <input type="text" class="form-control" id="hobbies" placeholder="爱好" name="hobbies" value="{{ student.hobbies }}">
            </div>
          
            <button type="submit" class="btn btn-default">提交</button>
          </form>
        </div>
      </div>
    </div>
  </body>
</html>

 

new.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>添加学生</title>

    <!-- Bootstrap core CSS -->
    <!-- <link href="/node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet"> -->
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="/public/css/main.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]-->
  </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/new" method="post">
            <div class="form-group">
              <label for="name">姓名</label>
              <input type="text" class="form-control" id="name" placeholder="姓名" name="name">
            </div>
            <div class="form-group">
              <label >性别</label>
              <div>
                <label class="radio-inline">
                <input type="radio" name="gender" id="gender" value="0"> 男
                </label>
                <label class="radio-inline">
                <input type="radio" name="gender" id="gender" value="1"> 女
                </label>
              </div>
            </div>
            <div class="form-group">
              <label for="age">年龄</label>
              <input type="number" class="form-control" id="age" placeholder="年龄" name="age">
            </div>
            <div class="form-group">
              <label for="hobbies">爱好</label>
              <input type="text" class="form-control" id="hobbies" placeholder="爱好" name="hobbies">
            </div>
          
            <button type="submit" class="btn btn-default">提交</button>
          </form>
        </div>
      </div>
    </div>
  </body>
</html>

 

 app.js

var express = require('express')
var app = express()
var fs = require('fs')
var router = require('./router.js')
var bodyParser = require('body-parser')
app.engine('html',require('express-art-template'))
app.use('/node_modules/', express.static('./node_modules/'))
app.use('/public/', express.static('./public/'))
//配置body-parser中间件,这两部一定要放在挂载路由之前
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
//把路由挂载到app服务中
app.use(router)
// router(app)
app.listen(3000, function () {
	console.log('app is running……')
})

rooter.js

// 功能:根据请求方式和请求路径设置具体的处理函数
//目的是增强代码的可维护性
var fs = require('fs')
//1、专门用来包装路由的
var express = require('express')
//2、创建一个路由
var router = express.Router()
//3、把router挂载到router路由器中

var Student = require('./student.js')
router.get('/', function (req, res)  {
	Student.find(function (err, data) {
		if (err) {
			//设置状态码为500,并告诉客户端服务错误
			return res.status(500).send('Server err.')
		}
		res.render('index.html', {
		fruits: [
			'苹果',
			'橘子',
			'梨'
		],
		// 将字符串转json数据格式,返回的是一个json数据,取里面的student
		students: data
		})
	})
// readFile的第二个参数是可以选择的,指把数据按照utf8转换成我们能认识的字符串
//readfile默认返回的是二进制数据
//或者用data.toString()也可以
	// fs.readFile('./db.json', 'utf-8', function (err, data) {
	// 	if (err) {
	// 		//设置状态码为500,并告诉客户端服务错误
	// 		return res.status(500).send('Server err.')
	// 	}
	// 	res.render('index.html', {
	// 	fruits:[
	// 		'苹果',
	// 		'橘子',
	// 		'梨'
	// 	],
	// 	// 将字符串转json数据格式,返回的是一个json数据,取里面的student
	// 	students:JSON.parse(data).student
	// 	})
	// })
})

router.get('/students/new', function (req,res) {
	res.render('new.html')
})

router.post('/students/new', function (req,res) {
	// console.log(req.body.gender)
	// console.log(req.body)
	//获取表单数据
	//放到db.json文件中,用以持久化
	//回应
		//先读出来,在转成对象,再往对象中push
		//再把对象转字符串,在往文件中写入
	Student.save(req.body, function (err) {
		if (err) {
			return res.status(500).send('Server err!')
		}
		res.redirect('/')
	})
})

router.get('/students/edit', function (req,res) {
	// res.render('edit.html')
	Student.findById(parseInt(req.query.id), function (err, stu) {
		if (err) {
			return res.status(500).send('Server err!')
		}
		res.render('edit.html', {
			student: stu
		})
	})
})

router.post('/students/edit', function (req,res) {
	Student.updateById(req.body, function (err) {
		if (err) {
			return res.status(500).send('Server err!')
		}
		res.redirect('/')
	})
})

router.get('/students/delete', function (req,res) {
	Student.deleteById(req.query.id, function (err) {
		if (err) {
			return res.status(500).send('Server err!')
		}
		res.redirect('/')
	})
})

module.exports = router


// module.exports=function (app) {
// 	app.get('/', function (req, res)  {
// 	// readFile的第二个参数是可以选择的,指把数据按照utf8转换成我们能认识的字符串
// 	//readfile默认返回的是二进制数据
// 	//或者用data.toString()也可以
// 	fs.readFile('./db.json', 'utf-8', function (err, data) {
// 		if (err) {
// 			//设置状态码为500,并告诉客户端服务错误
// 			return res.status(500).send('Server err.')
// 		}
// 		res.render('index.html', {
// 		fruits:[
// 			'苹果',
// 			'橘子',
// 			'梨'
// 		],
// 		// 将字符串转json数据格式,返回的是一个json数据,取里面的student
// 		students:JSON.parse(data).student
// 	})
// 	})
// }

student.js

/**
*职责:操作文件中的数据,只关心数据,不关心业务
*是一套异步api
*/

var fs = require('fs')
var dbPath = './db.json'
/**
*获取学生列表
*callback函数的第一个参数为err,错误时为错误对象,成功时为null
*   第二个参数为数据,错误时为undefined,成功时为数据
*return []
*回调函数的作用:获取函数内部异步操作的结果
*/
exports.find = function (callback) {
	fs.readFile(dbPath, 'utf8', function (err, data) {
		if (err) {
			return callback(err)
		}
		callback(null, JSON.parse(data).student)
	})
}

/**
*查询单个学生
*根据学生id查询这个学生的所有信息
*返回的是这个学生的信息
*/
exports.findById = function (id, callback) {
	fs.readFile(dbPath, 'utf8', function (err, data) {
		if (err) {
			return callback(err)
		}
		//先把文件里的学生信息取出来
		var students = JSON.parse(data).student
		//查询到当前学号的学生
		var stu = students.find(function (item) {
			return item.id == parseInt(id)
		})
		callback(null,stu)
	})
}


/**
*添加学生
*/
exports.save = function (currentStudent, callback) {
	fs.readFile(dbPath, 'utf8', function (err, data) {
		if (err) {
			return callback(err)
		}
		//先把文件里的学生信息取出来
		var students = JSON.parse(data).student
		//设置当前学生的id,不会重复
		currentStudent.id = students[students.length - 1].id + 1
		if (currentStudent.gender=='0'){
			currentStudent.gender = '男'
		}else {
			currentStudent.gender = '女'
		}
		//将当前学生信息存入数组中
		students.push(currentStudent)
		//将所有信息转化成json字符串
		var fileData = JSON.stringify({
			student: students
		})
		//将所有信息放文件中
		fs.writeFile(dbPath, fileData, function (err) {
			if (err) {
				//出错了就报错误信息
				return callback(err)
			}
			//没出错执行回调函数
			callback(null)
		})

	})
}

/**
*修改学生
*/
exports.updateById = function (student, callback) {
	fs.readFile(dbPath, 'utf8', function (err, data) {
		if (err) {
			return callback(err)
		}
		var students = JSON.parse(data).student
		// 传进来的id是字符串类型
		student.id = parseInt(student.id)
		//把要修改的那个学生按学号找出来
		//find是es6里面的一个新方法
		//需要接收一个函数作为参数,当找到 item.id == student.id 时,返回那个元素或对象
		var stu = students.find(function (item) {
			return item.id == student.id
		})
		// 将修改的数据存入stu中
		for (var key in student) {
			//stu.key和stu[key]的区别
			stu[key] = student[key]
		}
		//这个学生的数据就在里面了,不需要在放进去一遍
		//修改完之后放入students中
		// students.push(stu)
		if (stu.gender == 0) {
			stu.gender = "男"
		}else {
			stu.gender = "女"
		}
		var fileData = JSON.stringify({
			student: students
		})
		fs.writeFile(dbPath, fileData, function (err) {
			if (err) {
				return callback(err)
			}
			callback(null)
		})
	})
}

/**
*删除学生
*/
exports.deleteById = function (id, callback) {
	fs.readFile(dbPath, function (err, data) {
		if (err) {
			return callback(err)
		}
		var students = JSON.parse(data).student
		// var stu = student.find(function (item) {
		// 	return item.id == parseInt(id)
		// })
	    // findIndex 是es6的方法,专门用来查找元素的下标
		var deleteId = students.findIndex(function (item) {
			return item.id == parseInt(id)
		})
		students.splice(deleteId, 1)
		var fileData = JSON.stringify({
			student: students
		})
		fs.writeFile(dbPath, fileData, function (err) {
			if (err) {
				return callback(err)
			}
			callback(null)
		})

	})
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值