首先来说说我在搭建之前都先了解了什么:npm 包管理器、node模块、包的概念,前后端分离,模板的渲染、mongodb数据库、数据库操作,数据库的链接、用Romogondb工具可视化数据库及连接操作等。

建站目录

本次demo的练习让我理清了node开发的基本流程及前后端逻辑。
在开发之前,建好项目目录我觉得这是最重要的,在建站之前,你必须建立一些需求,我是打算写一个关于图书管理,共四个页面的网站,首页、后台数据录入页、列表数据页(用来获取数据库中的全部数据展现在页面上)、详情页(每一个id对应的数据页),然后链接数据库,实现数据库的添加、查找、修改、删除操作。下面是我的目录:

- db#用来存放启动数据库的数据
- models#用来存放对象在数据库中模型
- node_modules#用来存放项目所需的模板
- public#用来放前端的js、css、images文件
- routes#存放后端路由
- schemas#用来存放对象所需的字节信息
- views#存放视图模板的目录
- app.js#项目的入口文件
- package.json#包管理文件

具体如下:

html 如何部署到nginx_数据库

建站实施

我用的视图模板是html,他没有自动填充后台接口数据的语法,所以我用的是传统的ajax请求实现数据的获取,下面我就直接粘代码了,很多解释我都有代码注释的,在开发中遇到的问题我也会描述的。

  • 入口文件:app.js
var express = require('express');
var mongoose=require('mongoose');//引入模块
var path = require('path');
/*var _ = require('underscore');*///新更新的数据替换
var Book = require('./models/book');
var bodyParser = require('body-parser');
var swig = require('swig');

//创建web实例
var app = express();

var admin = require('./routes/admin');
var index = require('./routes/index');
var list = require('./routes/list');
var watch = require('./routes/watch');

//定义模板
app.engine('html', swig.renderFile);
//设置模板目录
app.set('views', './views');
//注册模板
app.set('view engine', 'html');
/*//取消模板缓存
swig.setDefaults({cache:false});*/

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//express配置静态文件
app.use(express.static(path.join(__dirname, 'public')));

//各路由
app.use('/admin', admin);
app.use('/', index);
app.use('/list', list);
app.use('/watch', watch);

app.listen(3000, function(){
    console.log('app is listening at port 3000');
});

//连接数据库
mongoose.connect('mongodb://localhost:27017/book',function(err){
    if(err){
        console.log('数据库连接错误了哦');
    }else{
        console.log('数据库连接成功了!你很棒棒哦!');
        app.listen();
    }
});

module.exports = app;
  • 各路由
    admin.js
var express = require('express');
//创建路有对象
var  router = express.Router();
var Book =require('../models/book');

router.get('/', function(req, res){
    res.render('admin/admin');
});
//统一返回格式
var responseData = null;
router.use(function(req,res,next){
    responseData={
        message:'',
        bookInfo: ''
    }
    next();
});

//后台录入数据
router.post('/bookinfo', function(req, res){
/*    var id = req.body.book._id;*/
    var bookname = req.body.bookname;
    var username = req.body.username;
    var publishtime = req.body.publishtime;
    var bookinfo = req.body.bookinfo;
    var _book;

    if(bookname == '' || username == '' || publishtime == '' || bookinfo == ''){
        responseData.message = '需要输入全部的数据!';
        res.json(responseData);
        return;
    }

    //查看所录入的书本信息是否存在
    Book.findOne({
        bookname: bookname
    }).then(function(bookInfo){
        if(bookInfo){
            responseData.message = '该书已经存在,可对他进行更新';
            res.json(responseData);
            _book = new Book({    
               bookname: bookname,
               username: username,
               publishtime: publishtime,
               bookinfo: bookinfo,
            });
            return _book.save();
        }else{
            _book = new Book({    
               bookname: bookname,
               username: username,
               publishtime: publishtime,
               bookinfo:bookinfo,

            });
            return _book.save();
        }
    }).then(function(newBookInfo){
        responseData.message='数据录入成功!';
        responseData.bookInfo = _book;
        res.json(responseData);
        //res.redirect('/list.html');
    });

});

module.exports = router;

index.js

var express = require('express');
//创建路有对象
var  router = express.Router();
var Book = require('../models/book');

router.get('/', function(req, res){
    res.render('index');
});

//统一返回格式
var responseData = null;
router.use(function(req,res,next){
    responseData={
        message:'',
        bookInfo: ''
    }
    next();
});

router.get('/index', function(req, res){
    Book.find(function(err, books){
        if(err){
            console.log(err);
        }else{
            responseData.message = '所有数据查询成功';
            responseData.bookInfo = books;
            res.json(responseData);
            return;
        }
    });
});

module.exports = router;

list.js

var express = require('express');
//创建路有对象
var  router = express.Router();
var Book =require('../models/book');
//统一返回格式
var responseData = null;
router.use(function(req,res,next){
    responseData={
        message:'',
        bookInfo: ''
    }
    next();
});

router.get('/', function(req, res){
    res.render('admin/list');
});

//数据列表
router.get('/listnew', function(req, res){
    Book.find(function(err, books){
        if(err){
            console.log(err);
        }else{
            responseData.message = '所有数据查询成功';
            responseData.bookInfo = books;
            /*responseData.bookInfo.id = books._id;*/
            res.json(responseData);
            return;
        }
    });
});

//更新数据
//直接去后台页面
//删除数据
router.delete('/delete', function(req, res){
    var id = req.query.id;

    if(id){
        Book.remove({
            _id: id
        }, function(err,book){
            if(err){
                console.log(err);
            }
            responseData.message = '数据删除成功';
            res.json(responseData);
            return;
        });
    }
});

module.exports = router;

watch.js

var express = require('express');
//创建路有对象
var  router = express.Router();
var Book =require('../models/book');

router.get('/', function(req, res){
    res.render('admin/watch');
});

//统一返回格式
var responseData = null;
router.use(function(req,res,next){
    responseData={
        message:'',
        bookInfo: ''
    }
    next();
});

//详情页/展示页
router.get('/look', function(req, res) {
    var id = req.query.id;

    Book.findOne({
        _id: id
    }).then(function(book){
        if(!book){
            responseData.message='该id在数据库中不存在!';
            res.json(responseData);
            return;
        }else{
            responseData.message='获取当前页面成功!';
            responseData.bookInfo = book;
            res.json(responseData);
            return;
        }
    });
});


module.exports = router;

上面这些是后台路由的代码,前端的请求脚本代码我不打算放了,相信我这种水平能做的,大家都能实现的,

  • 图书数据模式schemas
//book.js
//模式
//这里面放与书相关的信息
var mongoose = require('mongoose');
var Schema = mongoose.Schema;


var BookSchema = new Schema({
    bookname: String,
    username: String,
    publishtime: Number,
    bookinfo:String,
    meta:{
        createAt:{
            type: Date,
            default: Date.now()
        },
        updateAt: {
            type: Date,
            default: Date.now()
        }
    }
});

//为模式添加方法
//每次保存一个book数据之前都会调用这个方法
BookSchema.pre('save', function(next){
    if(this.isNew) {
        this.meta.createAt = this.meta.updateAt = Date.now();
    }else{
        this.meta.updateAt = Date.now();
    }

    next();
});

//静态方法,通过模型实例化之后才会有效
BookSchema.static = {
    //取出目前数据库所有的数据
    fetch: function(cb){
        return this
            .find({})
            .sort('meta.updateAt')//通过时间顺序对数据进行排序
            .exec(cb);//执行回调方法
    },
    findById: function(id, cb){
        return this
            .findOne({_id: id})
            .exec(cb); 
    }
};

module.exports = BookSchema;
  • 图书数据模型
//book.js
//模型
//用来初始化一个模式,成为一个有用的数据库对象
var mongoose = require('mongoose');
var BookSchema = require('../schema/book');
var Book = mongoose.model('Book', BookSchema);

module.exports = Book;
  • 测试网站效果
  • 开启数据库:我是使用最原始的方式,在本地下好的mogondb数据库文件下找到bin目录,打开mogond.exe文件,然后在romogondb工具下建立一个链接name,链接即可开启数据库;或是在bin目录下cmd运行下面命令
mongod --dbpath=(项目放数据库运行数据的文件目录,及这里的db文件夹目录) --port=27017 #这是链接数据库端口号,可以自己设定
  • 开启express服务器:在项目目录下运行命令
node app.js

如果显示数据库已经链接好了,便可以在浏览器中查看效果了:

localhost:3000 #首页
localhost:3000/admin #后台管理页
localhost:3000/list #列表页
  • 问题
  • 查看详情页
    我们通过a标签的href属性,查询字符串的形式传给后台相应的id,然后查看该ID的所以信息,在展示到页面上,请求代码如下:
$.ajax({
            type: 'GET',
            url: 'watch/look?id='+getSearchString('id'),
            data: {
               // id: getSearchString('id')
            },
            dataType:'json',
            success: function(data){
                var data = data.bookInfo;
                 //展示到页面。。。
            },
            error: function(){
                console.log(err);
            }
        });
  • 网站截图如下
    首页

    后台管理

    列表页

    romongodb工具使用
建站总结

学习node已经断断续续已经差不多三个月了,用心的学习效果还是很棒的,这个网站很简单,但是基本的一些功能有实现,所以会在继续添加新的功能,node学习中,我觉得最重要的是把前后端分离,逻辑分清,然后就是异步编程的使用。大概就是这些了,希望这次的练习能让自己得到一些成长,自己也会继续学习提升能力的。