http://www.cnblogs.com/andy1987/p/3745807.html
对nodejs和jqm的一次简单应用,构建一个简单的支持CRUD操作的页面.服务端用nodejs,前端使用JQM,数据存储使用mongodb。web框架用的是expressjs, 数据库操作插件使用的是mongoose,网页模板用的jade, 程序运行 如图:
一. 开篇准备
首先你必须确认你的系统安装了nodejs, mongodb
1.web框架用的是expressJs 3.x ,目前最新的是4.x版本,新版本和旧版本的主要区别:(路由设计基于restful, 所以你可以使用轻量级的restful服务器restify 来设计)
=> 4.x去除了类似bodyParser,cookieParser等功能中间件的绑定,使用需要单独下载。 4.x版本去除了route新增了新的路由实例 4.x去除了configure方式来配置环境和运行实例参数 => 更多的可以参考 http://scotch.io/bar-talk/expressjs-4-0-new-features-and-upgrading-from-3-0
2.数据库使用的是mongodb,操作用的mongoose
mongoose参考:http://mongoosejs.com/
3.web模板用是jade.
4.各种插件的安装: npm install 包 => 例如: npm install mongoose
二. 应用文件的组织结构
| = / + /views 存放视图文件(index.jade,layout.jade) + /public 存放静态文件( css,javascript,图片等) + /node_modules 存放nodejs依赖库(expressjs,mongoose等) + index.js 主文件,服务端 + package.json 配置文件(我们未使用)
三.服务端index.js
1.数据库应用,使用mongoose
=> 数据库连接: mongoose.connect('mongodb://localhost/fruitdb'); mongoose采用文档组织方式来格式化数据,例如新建数据: var Schema = mongoose.Schema; var FruitSchema = new Schema( { //字段定义 title: {type : String , require: true }, content:{type: String , require: true } //+> other field }); //生成数据模型 var FruitModel = mongoose.model( 'fruit' , FruitSchema ); => 数据模型才是真正操作数据库的关键,而schema仅仅是一种文档的组织结构. 数据的查找通过 find({option}, callback) 或者findById, 数据存储使用save(callback)方法
2.路由设计使用expressjs的路由功能
通过express的get ,post,put和del方法来实现CRUD操作,如果你使用的expressjs 4.x版本依然可以使用http get/post/put/del方法,还可以使用expressjs的router实例. 关于router实例参考: http://expressjs.com/4x/api.html#router 表单的解析可以使用bodyParser中间件 => 3.x app.use(express.bodyParser()); 如果你希望强壮和扩展该实例,可以添加session或者cookie功能,那你可以参考express的中间件列表: https://github.com/senchalabs/connect#middleware => 创建服务器并监听:可以直接使用app.listen(port)或者使用nodejs的原生http模块http.createServer(app).listen(port);
3.服务端代码 index.js
//=> nodejs + jqm example //=> by andy var express = require('express'), //express 3.x mongoose = require('mongoose'), mongodb = require('mongodb'), path = require('path'), Schema = mongoose.Schema; var app = module.exprots = express.createServer(); //配置,expressJS 4.x配置请参考: //http://scotch.io/bar-talk/expressjs-4-0-new-features-and-upgrading-from-3-0 app.configure(function(){ app.set('views' , __dirname + '/views'); app.set('view engine' ,'jade'); app.use( express.bodyParser()); app.use( express.methodOverride()); app.use( app.router ); app.use( express.static(path.join(__dirname , 'public'))); }); //log 打印请求的url和请求方式 app.use( function( req, res , next ){ console.log('method: %s , url: %s' ,req.method , req.url); }); //环境配置 app.configure( 'development' , function(){ app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); }); app.configure('production' , function(){ app.use(express.errorHandler()); }); //==> db config var ObjectId = mongodb.BSONPure.ObjectID; //连接fruitdb数据库 mongoose.connect('mongodb://localhost/fruitdb'); var db = mongoose.connection; db.on('error' , function(err){console.log(err);}); //模型定义 var FruitSchema = new Schema( { title: {type : String , require: true }, content:{type: String , require: true } //+> other field }); var FruitModel = mongoose.model('fruit' , FruitSchema ); //route app.get('/' , function(req, res , next){ FruitModel.find({} , function(err, data){ if( err ) return next(err); res.render('index',{ fruits:data}); }); }); //+> 新增 app.post('/fruits',function(req,res,next){ var obj = new FruitModel(); obj.title = req.body.title; obj.content = req.body.content; console.log("obj:%s" , JSON.stringify(obj)); obj.save( function(err){ if(err) return next(err); res.json({code:1 , message:'success save'}); }); }); //+> 返回所有水果 app.get('/fruits/list', function( req, res , next){ FruitModel.find({} , function( err, next){ if(err) return next(err); res.json(data); }); }); //+> 查看指定 app.get('/fruits/:id' , function(req,res,next){ FruitModel.findById({_id : ObjectID( req.params.id)} , function( err , data){ if( err ) return next(err); res.json( data ); }); }); //+> 删除 app.del('/fruits/:id' ,function( req, res , next){ FruitModel.findById({_id:ObjectID(req.params.id)} , function(err , data){ if( err ) return next(err); data.remove(function( err ){ res.json({code:1 , message:'success remove.'}) }); }); }) //=> 更新 app.put('/fruits/:id' , function(req, res , next){ FruitModel.update({_id:ObjectID(req.params.id)} , {title: req.body.title , content:req.body.content}, { upsert: false , multi:false}, function(err ){ if(err) return next(err); res.json( {code:1 , message:'success update'}); }); }); // if( !moudule.parent ){ // } //-> start listen app.listen('8888' , function(){ console.log('server has been started.'); });