您的位置:首页 > 数据库 > MySQL

整和angularjs,bootstrap,express4,mysql构建node项目

2015-09-07 14:17 691 查看

前 言

Nodejs给Javascript赋予了服务端应用的生命,Jquery让Javascript成为浏览中开发的利器。 最近学习了Nodejs的Express4.0的开发框架,浏览网上各种资料,由于版本原因自己模索中还是走了不少弯路的。写篇文章总结一下

转载请注明出处:

程序代码已经上传到github有需要的同学,自行下载。

https://github.com/xyl1993/nodeDemo

目录

1、建立工程

2、目录结构

3、app.js核心文件

4、Bootstrap界面框架

5、路由功能

6、Angularjs界面框架

7、程序代码

1、建立项目

准备工作:安装nodejs程序

1、全局安装express npm install -g express



安装完nodejs再全局安装express时成功后,输入express指令会提示'express' 不是内部或外部命令,也不是可运行的程序或批处理文件

此时可用npm install -g express-generator解决这个问题

安装完成后查看版本号



接下来我们使用express命令创建项目了

express -e nodeDemo #创建项目

cd nodeDemonpm install #依赖包安装

npm start #启动项目



2、目录结构

bin, 存放启动项目的脚本文件

bower_components,通过bower安装的第三方包

node_modules, 存放所有的项目依赖库

conf,mysql配置文件

dao,数据操作文件

public,静态文件(css,js,img)

routes,路由文件(MVC中的C,controller)

views,页面文件(Ejs模板,html页面)

package.json,项目依赖配置及开发者信息

app.js,应用核心配置文件

my_log4js.json,log4j配置文件



3、app核心配置

app.js:

//加载依赖库   加载之前需要通过npm进行安装
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');     //cookie
var bodyParser = require('body-parser');

//加载路由配置
var routes = require('./routes/index');
var users = require('./routes/users');
var ejs = require('ejs');

var session = require('express-session');           //session
var redisStore = require('connect-redis')(session);

var flash = require('connect-flash');
var log4js = require('log4js');               //log4j
var mysql = require('mysql');                //mysql
var app = express();

//log4js
log4js.configure('my_log4js_configuration.json',{});           //加载log4j配置文件
var logger = log4js.getLogger('nomel');
logger.setLevel('INFO');

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));

// app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(log4js.connectLogger(logger, {level: 'auto', format:':method :url'}));

app.use(session({
secret:'recommand 128 bytes random string',
cookie: {maxAge:60 * 1000}
}));

//定义静态文件路径
//这边一定要配置,否则加载静态资源时报404错误
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'bower_components')));
app.use(flash());

//定义模块引擎和模板文件位置,这边默认的是ejs,我 改为了html
app.engine('.html', ejs.__express);
app.set('view engine', 'html');// app.set('view engine', 'ejs');

//路由加载控制,根目录加载route,users目录加载users,在上方配置路径
app.use('/', routes);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});

app.use(session({
// 假如你不想使用 redis 而想要使用 memcached 的话,代码改动也不会超过 5 行。
// 这些 store 都遵循着统一的接口,凡是实现了那些接口的库,都可以作为 session 的 store 使用,比如都需要实现 .get(keyString) 和 .set(keyString, value) 方法。
// 编写自己的 store 也很简单
store: new redisStore(),
secret: 'somesecrettoken'
}));

exports.logger=function(name){
var logger = log4js.getLogger(name);
logger.setLevel('INFO');
return logger;
};

module.exports = app;


4、Bootstrap界面框架


创建Bootstrap界面框架,直接在index.ejs文件上面做修改。可以手动下载Bootstrap库放到项目中对应的位置引用,也可以通过bower来管理前端的Javascript库,参考文章 bower解决js的依赖管理。另外还可以直接使用免费的CDN源加载Bootstrap的css和js文件。下面我就直接使用Bootcss社区提供的CDN源加载Bootstrap。


[b]详细用法见bootstrap帮助文档:http://v3.bootcss.com/[/b]




这边要注意:放bootstrap的静态目录要在app中进行配置

5、路由功能


以我的路由配置为例:




var express = require('express');
var userDao = require('../dao/userDao');     //加载数据控制层
var router = express.Router();
var log = require('log4js').getLogger("index");          //加载log4j

/*以下是路由配置*/

/* GET home page. */
router.get('/', function(req, res, next) {
posts = [];
// res.render('index',{
// 		title:'首页',
// 		posts:posts,
// 		user: req.session.user,
//         success : req.flash('success').toString(),
//         error : req.flash('error').toString()
// 	})
res.render('main/index');
});

// router.get('/login',checkNotLogin); //通过公共方法判断用户是否登录
router.get('/login',function(req,res,next){
console.log("app.usr local");
res.locals.message = '';
var err = req.session.error;
delete req.session.error;
if (err) res.locals.message = '<div class="alert alert-error">' + err + '</div>';
res.render('login/login');
});

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

router.get('/guangzhu',function(req,res,next){
res.render('guangzhu/guanzhu');
});

router.get('/register',function(req,res,next){
res.render('register',{title:'用户注册'});
});

router.get('/home',function(req,res,next){
console.log('ok');
var user = {
username : 'admin',
password : 'admin'
}
res.locals.user = req.session.user;
log.debug(res.locals.user);
res.redirect('/');
});

router.get("/logout", checkLogin);
router.get('/logout',function(req,res,next){
req.session.user=null;
req.flash('success', '退出成功');
res.redirect('/');
});

/*路由配置end*/

//请求配置
router.post('/login',checkNotLogin);
router.post('/login',function(req,res,next){
userDao.queryById(req, res, next);
});

router.post('/register',function(req,res,next){
userDao.add(req, res, next);
});

// 检查用户登录状态
function checkNotLogin(req,res,next){
if(req.session.user){
req.flash('error','用户已经登录');
return res.redirect('/');
}
next();
}

function checkLogin(req,res,next){
log.debug(req.session.user);
if(!req.session.user){
console.log(req.session.user);
req.flash('error','用户未登录');
return res.redirect('/login');
}
next();
}
module.exports = router;
usersDao文件:

// dao/userDao.js
// 实现与MySQL交互
var mysql = require('mysql');
var $conf = require('../conf/db');        //加载配置项
var $util = require('../util/util');
var $sql = require('./userSqlMapping');    //加载mapping文件
var log = require('log4js').getLogger("userDao");
// 使用连接池,提升性能
var pool  = mysql.createPool($conf.mysql);

// 向前台返回JSON方法的简单封装
var jsonWrite = function (res, ret) {
if(typeof ret === 'undefined') {
res.json({
code:'1',
msg: '操作失败'
});
} else {
res.json(ret);
}
};

module.exports = {
add: function (req, res, next) {
pool.getConnection(function(err, connection) {
// 获取前台页面传过来的参数
var param = req.query || req.params;
// 建立连接,向表中插入值
// 'INSERT INTO user(id, name, age) VALUES(0,?,?)',
connection.query($sql.insert, [req.body.username, req.body.password], function(err, result) {
log.debug(result);
if(result) {
// result = {
// 	code: 200,
// 	msg:'增加成功'
// };
res.redirect('/login');
}

// 以json形式,把操作结果返回给前台页面
// jsonWrite(res, result);

// 释放连接
connection.release();
});
});
},
delete: function (req, res, next) {
// delete by Id
pool.getConnection(function(err, connection) {
var id = +req.query.id;
connection.query($sql.delete, id, function(err, result) {
if(result.affectedRows > 0) {
result = {
code: 200,
msg:'删除成功'
};
} else {
result = void 0;
}
jsonWrite(res, result);
connection.release();
});
});
},
update: function (req, res, next) {
// update by id
// 为了简单,要求同时传name和age两个参数
var param = req.body;
if(param.name == null || param.age == null || param.id == null) {
jsonWrite(res, undefined);
return;
}

pool.getConnection(function(err, connection) {
connection.query($sql.update, [param.name, param.age, +param.id], function(err, result) {
// 使用页面进行跳转提示
if(result.affectedRows > 0) {
res.render('suc', {
result: result
}); // 第二个参数可以直接在jade中使用
} else {
res.render('fail',  {
result: result
});
}

connection.release();
});
});

},
queryById: function (req, res, next) {
// var id = +req.query.id; // 为了拼凑正确的sql语句,这里要转下整数
pool.getConnection(function(err, connection) {
connection.query($sql.queryByNameAndPwd, [req.body.user, req.body.password], function(err, rows,result) {
log.debug(rows);
var resMap = {};
var id = rows[0].id+'';
// jsonWrite(res, result);
if(id){
connection.query($sql.queryById,id,function(err,result){
log.debug(result);
var user={
username : result[0].name
};
req.session.user = user;
log.debug(req.session.user);
resMap.code=0;
resMap.data=result[0];
res.send(resMap);
})
}else{
req.session.error = '用户名密码不正确';
return res.redirect('/login');
}
connection.release();
// return result;

});
});
},
queryAll: function (req, res, next) {
pool.getConnection(function(err, connection) {
connection.query($sql.queryAll, function(err, result) {
jsonWrite(res, result);
connection.release();
});
});
}

};
mappin
ba57
g文件:

var user = {
insert:'INSERT INTO t_user(name, password) VALUES(?,?)',
update:'update t_user set name=?, password=? where id=?',
delete: 'delete from t_user where id=?',
queryById: 'select * from t_user where id=?',
queryByNameAndPwd:'select id from t_user where name=? and password=?',
queryAll: 'select * from t_user'
};

module.exports = user;


6、Angularjs


AngularJS是开发基于浏览器的响应式RWD应用程序的一个前端MVC框架,由谷歌最初开发的 开源项目,干净的架构吸引了大量粉丝,适合建立CRUD类型的业务应用程序,并不适合开发游戏等应用, 使用声明性编程的用户界面和命令式编程的逻辑, 支持现代桌面和移动浏览器 Internet Explorer版本8.0及以上。不得不说使用angularjs开发web项目真是爽

这边只介绍基础配置

以下为html实例代码

<!DOCTYPE html>
<html lang="en" ng-app="main">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>首页</title>

<link rel="shortcut icon" href="../../common/images/favicon.ico" />
<!-- Bootstrap -->
<link href="/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/bootstrap/dist/css/bootstrap-theme.min.css" rel="stylesheet">

<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body class="main">
<!-- <div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div class="hero-unit">
<h1>
nodejs-demo
</h1>
<p>
学的不仅是技术,更是梦想!
</p>
<p>
再牛逼的梦想,也抵不住你傻逼似的坚持!
</p>
</div>
</div>
</div>
</div> -->
<div class="main-left">
<ul class="main-left-ul">
<li>
<span>简</span>
</li>
<li>
<span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
</li>
<li>
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
</li>
<li>
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
</li>
<li>
<span class="glyphicon glyphicon-phone" aria-hidden="true"></span>
</li>
</ul>
</div>
<div class="clear"></div>
<div>
<div class="dyn-img-box">

</div>
<div class="dyn-content-box">
<div>
<div class="box-tit">
<ul class="dyn-box-tit">
<li ui-sref="found"><span>发现</span></li>
<li ui-sref="guanzhu"><span>光注</span></li>
<li><span class="glyphicon glyphicon-cog"></span></li>
</ul>
</div>
<div class="main-content-box" ui-view>    //ui-view视图加载核心指令
</div>
</div>
<div>

</div>
</div>
</div>

<!-- jquery -->
<script type="text/javascript" src="/javascripts/jquery.min.js"></script>
<!-- bootstrap -->
<script type="text/javascript" src="/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- angularjs -->
<script type="text/javascript" src="/angularjs/angular.js"></script>            //引入angularjs
<script type="text/javascript" src="/angularjs/angular-ui-router.js"></script>       //ui-route路由
<script type="text/javascript" src="/angularjs/angular-sanitize.min.js"></script>
<script type="text/javascript" src="/angularjs/angular-resource.min.js"></script>

<!-- w5v -->
<script type="text/javascript" src="/javascripts/w5cValidator.min.js"></script>
<!-- me js -->
<script type="text/javascript" src="/javascripts/main/main.js"></script>
</body>

</html>
main.js

var mainModule = angular.module('main', ['ui.router',
//全局配置			'ngResource', 'ngSanitize','w5c.validator']);
mainModule.run(function($rootScope, $state, $http, $stateParams, $location,$timeout,$window) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
})

//路由配置
mainModule.config(['$stateProvider','$urlRouterProvider',function($stateProvider,$urlRouterProvider) {
$stateProvider.state('found',{
url : '/found',               //注意这边的url路径要在路由里面进行get配置
templateUrl : '../found'
}).state('guanzhu',{
url : '/guanzhu',               //发现
templateUrl : '../guangzhu'
})
}])

//控制器
mainModule.controller('testController', ['$scope', function($scope){

}])


//写一个ajax请求测试后台

$(function(){
$('#logIn').click(function(event) {
/* Act on the event */
var data={
'user' : $('#userName').val(),
'password' : $('#password').val()
};
$.ajax({
method : 'post',
url : '/login',
data:data
}).success(function(resp){
console.log(resp.code);
var data = resp.data;
console.log(data.name);
if(resp.code===0){
window.location.href="../home";
}
}).error(function() {
/* Act on the event */
console.log('aa');
});
});
})


7、程序代码




这个项目托管在github上,地址为:[b]https://github.com/xyl1993/nodeDemo[/b]


在里面readme.md中写了启动方法






我的个人博客,https://nodeblog-xylblog.rhcloud.com/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息