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

前 言

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。

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

这边要注意:放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();
			});
		});
	}
 
};
mapping文件:

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上,地址为:https://github.com/xyl1993/nodeDemo

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


大笑

我的个人博客,https://nodeblog-xylblog.rhcloud.com/


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值