整和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/
相关文章推荐
- bootstrap初试进度条
- Bootstrap 3.3.4 发布,Web 前端 UI 框架
- 交换机升级排障实例
- 使用ruby部署工具mina快速部署nodejs应用教程
- Google官方支持的NodeJS访问API,提供后台登录授权
- nodejs教程之环境安装及运行
- nodejs中的fiber(纤程)库详解
- 基于NodeJS的前后端分离的思考与实践(五)多终端适配
- 基于NodeJS的前后端分离的思考与实践(二)模版探索
- 我的NodeJs学习小结(一)
- nodejs中实现sleep功能实例
- Nodejs异步回调的优雅处理方法
- sql2008启动代理未将对象应用到实例解决方案
- Windows系统下使用Sublime搭建nodejs环境
- nodejs实现获取某宝商品分类
- nodejs简单实现中英文翻译
- Node.js插件的正确编写方式
- 使用upstart把nodejs应用封装为系统服务实例
- NodeJS Web应用监听sock文件实例
- Nodejs学习笔记之测试驱动