## 1. 先打开编辑器,创建一个项目

## 2. 再打开cmd命令提示符下载express脚手架

express   项目名   --view=ejs 或express   -e    项目名

## 3. 在cmd中进入项目名(myapp)下载所需的依赖

cd myapp  --------->cnpm  install

## 4. 在下载mongoose(前提你电脑上要安装数据库的插件)

cn cnpm mongoose  --save

## 5. 在myapp项目中在创建一个文件夹,里面在新建三个文件

文件夹名  lib    ------->三个文件名  mongoose.js    schema,js     appModel.js

## 6. 在mongoose.js 中连接数据库

//先引入mongoose模块

var mongoose=require("mongoose");

//连接数据库服务器

mongoose.connect("mongodb://localhost/数据库名(bao)",function(error){

if(error){

console.log("数据库连接失败")

}else{

console.log("数据库连接成功")

}

})

//导出

module.exports=mongoose;

## 7. 在schema.js 文件中定义schema

//引入mongoose.js文件

var mongoose=require("./mongoose.js")      //这里的.js可省略不写

//定义schema

var   schema=mongoose.Schema({

//这里是数据库自己创建的属性名:他的属性类型   如:

                id:String,
name:String,
age:Number,
tel:Number

})

//导出

module.exports=schema;

## 8. 在appModel.js 文件中定义模型

//引入mongoose.js 文件

var mongoose=require("./mongoose");

//引入schema.js 文件

var schema=require("./schema");

//定义模型

var appModel=mongoose.model("appModel",schema,"数据库中的集合名(app)");

//导出

module.exports=appModel;

## 9. 在views文件夹中找到index.els编辑

//先引入bootstrap的css样式,js样式,不过要把jquery的js插件引入在bootstrap.js的前面,bootstrap连接的样式可通过本地下载,也可网上连接地址即可

//本地下载    cnpm install bootstrap   --save

//通过Bootstrap官网找到我们需要的样式直接复制粘贴

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>留言板练习</title>
<link rel="stylesheet" href="css/bootstrap.css">
<style>
.box{
margin: 100px auto;
}
table{
margin: 100px auto;
}
table th{
text-align: center;
}
</style>
</head>
<body>
<!--添加的表单-->
<div class="container box">
<form>
<div class="form-group">
<label for="xh">学号:</label>
<input type="text" class="form-control" id="xh" placeholder="请输入学号">
</div>
<div class="form-group">
<label for="xm">姓名:</label>
<input type="text" class="form-control" id="xm" placeholder="请输入姓名">
</div>
<div class="form-group">
<label for="nl">年龄:</label>
<input type="text" class="form-control" id="nl" placeholder="请输入年龄">
</div>
<div class="form-group">
<label for="tel">电话:</label>
<input type="text" class="form-control" id="tel" placeholder="请输入电话">
</div>
<button type="button" class="add btn btn-info">添加</button>
<button type="reset" class="btn btn-info">重置</button>
</form>
<!--表格-->
<table class="table table-bordered text-center">
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>电话</th>
<th>操作</th>
</tr>
</thead>
<tbody> <tr>
<td>1</td>
<td>张三</td>
<td>20</td>
<td>男</td>
<td>
<button type="button" class="del btn btn-warning">删除</button>
<button type="button" class="xg btn btn-danger">修改</button>
</td>
</tr>
<tr>
<td>2</td>
<td>李四</td>
<td>20</td>
<td>男</td>
<td>
<button type="button" class="del btn btn-warning">删除</button>-->
<button type="button" class="xg btn btn-danger">修改</button>-->
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<button type="button" class="delAll btn btn-warning">全部删除</button>
</td>
</tr>
</tfoot>
</table>
<!--模态框,当点击修改按钮时,弹出此框-->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">修改数据</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="xh">学号:</label>
<input type="text" class="xh form-control" id="xh" placeholder="请输入学号">
</div>
<div class="form-group">
<label for="xm">姓名:</label>
<input type="text" class="form-control xm" id="xm" placeholder="请输入姓名">
</div>
<div class="form-group">
<label for="nl">年龄:</label>
<input type="text" class="form-control nl" id="nl" placeholder="请输入年龄">
</div>
<div class="form-group">
<label for="tel">电话:</label>
<input type="text" class="form-control tel" id="tel" placeholder="请输入电话">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="bc btn btn-primary" data-dismiss="modal">保存</button>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
<script src="js/jquery-3.4.1.js"></script>
<script src="js/bootstrap.js"></script>

## 10. 在routes路由文件夹中创建两个文件

index.js 渲染页面的二级路由   users.js增删改查的接口

## 11. 在app.js中引入这两个二级路由文件

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
app.use('/', indexRouter);
app.use('/api', usersRouter);

## 12. 在index.js文件中

//引入express模块
var express = require('express');
//获取路由
var router = express.Router();
//引入model.js文件
var mm=require("../lib/appModel");
//设置渲染页面路由
/* GET home page. */
//主页从数据库找到数据,返回前台,并渲染
router.get('/', function(req, res, next) {
mm.find({},function (err,docs) {
if(err){
console.log("查找数据库数据失败")
}else{
res.render('index', { data:docs });
}
}) }); //导出路由
module.exports = router;

## 13. 在index.ejs 文件中渲染的部分

<tbody>
<%for(var i=0;i<data.length;i++){%>
<tr>
<td><%=data[i].id%></td>
<td><%=data[i].name%></td>
<td><%=data[i].age%></td>
<td><%=data[i].tel%></td>
<td>
<!--_id是数据库中自带的id号-->
<button v="<%=data[i]._id%>" type="button" class="del btn btn-warning">删除</button>
<button type="button" class="xg btn btn-danger" data-toggle="modal" data-target="#myModal">修改</button>
</td>
</tr>
<%}%>
</tbody>

## 14. 在users.js二级路由文件中设置增删改查

//增(也可以说是添加)

//引入express模块
var express=require("express"); //获取路由
var router=express.Router(); //引入model.js文件
var mm=require("../lib/model"); //设置数据接口路由 //添加数据到数据库
router.get("/write",function (req, res,next) {
var da=req.query;//获取前台请求的数据,返回来是一个对象
console.log(da)//{id:xh.name:xm,age:nl,tel:tel}
//实例化
var aa=new mm(da);//mm({id:..,name:..,age:..,tel:...})
//添加
aa.save(function (err) {
if(err){//如果失败就输出
res.send({
code:1,
message:"添加失败"
});
}else{//否则
res.send({
code:0,
message:"添加成功"
})
} }) });
//导出
module.exprots=router;

## 15. 在index.ejs中的 增 代码

$(".add").click(function () {
//获取学号,姓名,年龄,性别的内容
var xh=$("#xh").val();
var xm=$("#xm").val();
var nl=$("#nl").val();
var tel=$("#tel").val(); // alert(xh); alert(xm); alert(nl); alert(tel)检测获取数据成功 $.ajax({
url:"/api/write",
data:{
id:xh,
name:xm,
age:nl,
tel:tel
},
success:function (ret) {//成功返回数据
console.log(ret) },error:function (msg) {//失败返回数据
console.log(msg)
}
})
});

## 16. 解决点击添加按钮后,要刷新一次才能把添加的内容显示在页面

//1. 可以是添加完,是整个页面刷新("location.href="/"  "),但是有因为下面的表格式要异步更新的,所以不能整个页面刷新

//2. 我们要让它点击添加按钮后,tbody的里面内容变空$("tbody").html(" "),在通过ajax读取后台数据库里的数据,把他渲染,添加到当前的tbody里

//读取数据库里的数据

//读取数据库中的数据
router.get("/read",function (req, res, next) {
mm.find({},function (err,docs) {
if(err){
res.send({
code:2,
message:"读取数据失败"
});
}else{
res.send({
code:0,
data:docs,
message:"读取数据成功"
})
} }) });

//通过ajax渲染添加到页面

/*添加数据,,,用ajax*/
$(".add").click(function () {
//获取学号,姓名,年龄,性别的内容
var xh=$("#xh").val();
var xm=$("#xm").val();
var nl=$("#nl").val();
var tel=$("#tel").val(); // alert(xh); alert(xm); alert(nl); alert(tel)检测获取数据成功 $.ajax({
url:"/api/write",
data:{
id:xh,
name:xm,
age:nl,
tel:tel
},
success:function (ret) {//成功返回数据
console.log(ret);
if(ret.code==0){ //在这里判断后
//当后台返回数据是写入数据成功,让当前的tbody中的内容变空,
$("tbody").html("");
//在通过ajax读取后台在数据库中的内容,在渲染到tbody中
add(); //封装的函数
} },error:function (msg) {//失败返回数据
console.log(msg)
}
})
});

//在这里因为后面都需要用到,所以封装到函数里,后面用的话直接调用就可以了

//包装函数
function add(){
$.ajax({
url:"/api/read",
success:function(ret){
if(ret.code==0){
var str="";
var data=ret.data;
for(var i in data){
str+=`<tr>
<td>${data[i].id}</td>
<td>${data[i].name}</td>
<td>${data[i].age}</td>
<td>${data[i].tel}</td>
<td>
<button v="${data[i]._id}" type="button" class="del btn btn-warning">删除</button>
<button type="button" class="xg btn btn-danger" data-toggle="modal" data-target="#myModal">修改</button>
</td>
</tr>`
}
$("tbody").html(str);
//当渲染后(局部更新后)让当前的学号,姓名,年龄,电话框都为空
$("#xh").val("");
$("#xm").val("");
$("#nl").val("");
$("#tel").val("");
}
},error:function (msg) {
console.log(msg)
}
})
}

## 17. 全部删除   users.js

//全部删除数据
router.get("/delAll",function (req, res, next) {
mm.remove({},function (err) {
if(err){
res.send({
code:3,
message:"全部删除失败"
});
}else{
res.send({
code:0,
message:"全部删除成功"
})
}
})
});

## 18. 全部删除   index.ejs

//全部删除
$(".delAll").click(function () {
$.ajax({
url:"/api/delAll",
success:function (ret) {
console.log(ret);
if(ret.code==0){
add();
}
},error:function (msg) {
console.log(msg);
}
})
});

## 19. 单行删除   users.js

//单行删除
router.get("/del",function (req, res, next) {
//获取前台请求的数据
var data=req.query;
mm.remove(data,function (err) {
if(err){
res.send({
code:4,
message:"单行删除失败"
});
}else{
res.send({
code:0,
message:"单行删除成功"
})
}
})
});

## 20. 单行删除   index.ejs

//单行删除,需要用到事件委托
$("tbody").on("click",".del",function () {
// alert(111)
//获取_id的值,来确定当前行的位置(如:id,name,age,del都可)
var a=$(this).attr("v");
// alert(a);//检测当前弹出的_id是否不同
$.ajax({
url:"/api/del",
data:{
_id:a
},
success:function (ret) {
console.log(ret);
if(ret.code==0){
add();
}
},error:function (msg) {
console.log(msg);
} })
});

## 21. 修改数据  users.js

//修改数据库内容
router.get("/xg",function (req, res, next) {
//获取前台请求数据
var data=req.query;
console.log(data);
//获取前台的_id
console.log(data.f);
//获取前台的数据请求
console.log(data.da);
//修改数据
mm.update(data.f,data.da,function (err) {
if(err) {
res.send({
code: 5,
message: "修改数据失败"
});
}else{
res.send({
code:0,
message:"修改数据成功"
}); } }) });

## 22. 修改数据  index.ejs

// 当点击修改时,获取他的兄弟元素删除的_id,渲染的都需要用到事件委托
$("tbody").on("click",".xg",function () {
var a=$(this).siblings().attr("v");
// alert(a)//检测他兄弟删除的_id $(".bc").attr("v",a);//将他兄弟删除的属性也添加成了自己的属性
}); // 当点击弹框保存时,修改数据,有点问题,一次只能修改一次,下次要刷新
$(".bc").click(function () {
//attr一个参数是获取,两个参数是设置
var _id=$(this).attr("v");
alert(_id)
//获取弹框里的学号,姓名,年龄,性别的内容
//注意:这里要用class名,id名只能用一次
var xh=$(".xh").val();
var xm=$(".xm").val();
var nl=$(".nl").val();
var tel=$(".tel").val();
// alert(xh); alert(xm); alert(nl); alert(tel);
//ajax
$.ajax({
url:"/api/xg",
data:{
f:{
_id:_id
},
da:{
id:xh,
name:xm,
age:nl,
tel:tel
}
},
success:function (ret) {
console.log(ret);
if(ret.code==0){
$("tbody").html("");
add();
}
},error:function (msg) {
console.log(msg)
} }) });

## 23. 到这里项目就结束了,说明一下:我也是一个刚学的小白,这个修改数据里有点小问题,等你自己去发现哟!

有哪位大佬解决了这个bug,请留言告诉我哟,在此不胜感激!!

nodejs中利用expresss脚手架和bootstrap,数据库mongodb搭建的留言板案例的更多相关文章

  1. 在VB中利用Nuget包使用SQLite数据库和Linq to SQLite

    上午解决了在C#中利用Nuget包使用SQLite数据库和Linq to SQLite,但是最后生成的是C#的cs类文件,对于我这熟悉VB而对C#白痴的来说怎么能行呢? 于是下午接着研究,既然生成的是 ...

  2. 在C#中利用Nuget包使用SQLite数据库和Linq to SQLite

    本来是学习在VB中使用SQLite数据库和Linq to SQLite,结果先学习到了在C#中使用SQLite数据库和Linq to SQLite的方法,写出来与大家共同学习.(不知道算不算不务正业) ...

  3. 在nodejs中利用 Proxy监听对象值的获取

    1 window = new Proxy(global, { 2 get: function (target, key, receiver) { 3 console.log("window. ...

  4. (转载)在Delphi中利用MSDASC来配置数据库链接

    在Delphi中利用MSDASC来配置数据库链接 在运行期进行数据库的连接是一个问题,自己写一个窗体配置吧,数据库不一样,所用的参数也不一样,还有那讨厌的连接字符串,有时真不知该写什么好.那天无意中发 ...

  5. nodejs中如何使用mysql数据库[node-mysql翻译]

    nodejs中如何使用mysql数据库 db-mysql因为node-waf: not found已经不能使用,可以使用mysql代替. 本文主要是[node-mysql]: https://www. ...

  6. SQL中利用脚本恢复数据库

    SQL中利用脚本恢复数据库   编写人:CC阿爸 2014-6-15 在日常SQL数据库的操作中,如何恢复数据库 use master drop database SCS1 RESTORE DATAB ...

  7. 利用express-session插件实现nodejs中登录状态的保存

    什么是session? session就是会话,客户端和服务器直接的会话.他的粒度比http链接更粗,一次会话包含了多次连接.即一个session是多次http连接的集合.从我的客户端连接到服务器到关 ...

  8. nodejs中常用加密算法

    在常用的nodejs+express工程中,为了安全在登录及表单传输时,应该都需进行加密传输,目前个人常用到的加密方式有下列几种: 1.Hash算法加密: 创建一个nodejs文件hash.js,输入 ...

  9. 浅谈nodejs中HTTP模块应用

    这里给大家分享下后端人员如果利用nodejs对数据的一些处理情况  适用于初学者使用 大牛勿喷 给大家分享下主要后端思想部分代码,前端部分就不展示了 const http = require(&quo ...

随机推荐

  1. learning java AWT Dialog

    import java.awt.*; public class DialogTest { Frame f = new Frame("test"); Dialog d1 = new ...

  2. Session的应用——三天免登录

    1.使用Cookie实现的登录的不足: protected void doGet(HttpServletRequest request, HttpServletResponse response) t ...

  3. Linux中三种SCSI target的介绍之SCST

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/scaleqiao/article/deta ...

  4. PHPStorm启动问题--Failed to load JVM DLL

    一.问题 启动PHPStorm时突然遇到PHPStorm无法启动的问题,提示:Failed to load JVM DLL,如图所示:

  5. 机器学习---用python实现最小二乘线性回归算法并用随机梯度下降法求解 (Machine Learning Least Squares Linear Regression Application SGD)

    在<机器学习---线性回归(Machine Learning Linear Regression)>一文中,我们主要介绍了最小二乘线性回归算法以及简单地介绍了梯度下降法.现在,让我们来实践 ...

  6. Processing 中玩增强现实 Argument Reality

    其实2009年Processing就能做AR了,只是我不知道而已~ 需要以下几个东西: 1.JMyron 2.GSVideo 3.nyar4psg 4.Picking 5.OBJLoader 或者大伙 ...

  7. Quartz.NET浅谈一 : 简单Job使用(定时发送QQ邮件)

    Quartz.NET是一个全功能的开源作业调度系统,可用于从最小的应用程序到大型企业系统. 直接上代码吧... 一.新建一个控制台项目 略过 二.安装Nuget包 三.创建发送邮箱辅助工具类 stat ...

  8. java.util之一:ArrayList

    ArrayList是java中的线性结构的一种表示方法,在java中使用频率非常高,下面来一步一步分析其底层的实现.(JDK1.8) 一.构造函数 ArrayList的构造函数有三个,分别如下, 我们 ...

  9. DNGuard HVM Unpacker(3.71 trial support and x64 fixed)

    DNGuard HVM Unpacker(3.71 trial support and x64 fixed) Gr8 news. Finally got the x64 crash fixed. DN ...

  10. 003 spring boot访问静态资源与重定向

    今天被问到重定向的问题,后续又引起了静态资源路径配置的问题,在这里做一个总结,当然,顺便添加默认访问index.html. 一:默认访问 1.默认路径 在springboot中静态资源的映射文件是在r ...