从零开始node.js入门项目(三)基本构架
2014-01-03 16:03
531 查看
基本构架
目录设置
按之前简单需求分析,项目前后台,兼顾扩展,所以还是需要个MVC的模式。按照平常习惯,在项目目录(d:/www/boss)中建立如下子目录
controllers 控制器
views 显示层
public 公共文件,包括js , images ,css 等
core 核心类,准备放一些基本的数据库操作类等
models 数据对象类
MVC模式思路及测试
根据其他项目经验,设想中的NODE.JS的MVC应该是这样工作的注意:目前还无法证实是否可行,也无法证明是否符合NODE.JS规范,新手瞎折腾而已,后面会查找资料一个个去测试。
1、所有来自客户端的请求到达入口文件,然后根据路由配置转到相应的controller-->action
2、action中根据请求的request,response做实现具体的业务逻辑,如渲染一个页面
下面写一些代码来一步步测试以上思路:
注:全是百度谷歌得出的结果,得到最终测试代码过程不记流水帐了,只给出重要注释和最终测试结果。
首先,解决请求到达index.js后如何路由出去
新建 /index.jsvar express = require('express'); //node.js的模块加载方法,直接调用require即可,路由处理全部放在核心公共类目录的routes.js中 var routes = require('./core/routes.js'); var app = express(); app.listen(80,'127.0.0.8'); //将所有请求交给路由去处理 routes(app);
新建 /core/routes.js
module.exports = function(app){ //app.all 是EXPRESS方法,匹配所有HTTP动作,包括get和post app.all('*',function(req,res){ res.send('hello routes'); }); };
运行后,在浏览器测试,得到预期结果 hello routes ,测试通过
第二个要解决的问题,路由器将请求转到指定的controller-->action
我们的路由应该是符合“约定大于配置”原则,根据请求按约定分发到指定程序。首先我们约定基本的路由规则:
规制一:所有的请求根据URL都可拆分为controller和action和parameters三部分
如:http://www.boss.xx/admin/login
这个请求的 controller=admin,action=login,parameters=null
如:http://www.boss.xx/user/view/id/25
这个请求的 controller=user,action=view,parameters={'id':25}
规制二:默认约定,有些情况下可以使用简写的路径,它也是符合第一个规则的,因为我们约定了默认规则
默认约定有:如果parameters为空则parameters=‘site’,如果action为空则action=‘index’,如果parameters不为空但参数的key为空,则key='id'
如:http://www.boss.xx/26
这个请求的controller=‘site’,action='index',parameters={'id':26}
下面我们来是现实这两个路由规则,
修改/index.js
var express = require('express'); var url = require('url'); //node.js的模块加载方法,直接调用require即可,路由处理全部放在核心公共类目录的routes.js中 var routes = require('./core/routes.js'); var app = express(); app.listen(80,'127.0.0.8'); //将所有请求交给路由去处理 routes(app,url);
修改/core/routes.js
module.exports = function(app,url){ //app.all 是EXPRESS方法,匹配所有HTPP动作,包括get和post app.all('*',function(req,res){ //res.send('hello routes'); var pathname = url.parse(req.url).pathname; var path=path_rule(pathname); res.send(path); }); }; function path_rule(pathname){ var parameters={}; if (pathname.substr (-1,1)=="/"){ pathname=pathname.substr(0,(pathname.length-1)) } if (pathname.substr (0,1)=="/"){ pathname=pathname.substr(1,pathname.length) } var path=pathname.split('/'); if (path.length==1 && path[0]=="" ){ path[0]="site"; path[1]="index"; } if (path.length==2 && path[1]==""){ path[1]="index"; } if (path.length==3){ var tmp=path[2]; path[2]="id"; path[3]=tmp; } if (path.length>3){ //将url后面部分全部转成参数 for (var i=2;i<path.length;i++){ if (path[i+1]=='undefined'){ path[i+1]=""; } if (i%2==0){ parameters[path[i]]=path[i+1]; } } } return { 'controller':path[0], 'action':path[1], 'parameters':parameters }; }
执行结果,通过
我们分解了URL,接着要把根据url让请求到达指定的action
在controller下新建site_controller.js
controller/site_controller.js代码
var controller=function(req,res){ this.res=res; this.req=req; }; controller.prototype.action_index=function(){ this.res.send('i am actionIndex'); }; controller.prototype.action_about=function(){ this.res.send(['BOSS系统','ver:0.01','author:BYTS','date:2014-1-1']); }; exports.controller = controller;
继续修改/core/routes.js ,这里我们实现了一个简单的动态方法调用
/core/routes.js
module.exports = function(app,url){ //app.all 是EXPRESS方法,匹配所有HTPP动作,包括get和post app.all('*',function(req,res){ //res.send('hello routes'); var pathname = url.parse(req.url).pathname; var path=path_rule(pathname); //载入controller,约定controller一定是放在./controllers目录,并且是name+_controller.js的命名方法 var c=require('../controllers/'+path.controller+'_controller.js'); var controller= new c["controller"](req,res); //执行载入controller类中的action方法,约定action一定是name+_action的方式 var action="action_"+(path.action).toLocaleLowerCase(); if (typeof(controller[action])=='function'){ controller[action](); }else{ res.send('找不到'+action); } }); };
运行代码,查看结果,预期目标将请求转到指定controller->action,通过
分别请求
http://www.boss.xx/ http://www.boss.xx/site/about http://www.boss.xx/site/xx
至此,路由构架完成,以后只要添加不同的_controller.js就可以了。
请求到达了action,下面我们要实现渲染html网页和使用模板。
第三个问题,渲染页面
其实这都不是一个问题,当初选express和ejs就是因为它们简单易用,express是个框架,框架就是帮我们做脏活的。。我们来实现一个登录页面,直接上代码:
修改:/index.js
var express = require('express'); var url = require('url'); //node.js的模块加载方法,直接调用require即可,路由处理全部放在核心公共类目录的routes.js中 var routes = require('./core/routes.js'); var app = express(); app.listen(80,'127.0.0.8'); app.set("view engine","ejs"); //将所有请求交给路由去处理 routes(app,url);修改controller/site_controller.js
var controller=function(req,res){ this.res=res; this.req=req; }; controller.prototype.action_index=function(){ this.res.send('i am actionIndex'); }; controller.prototype.action_about=function(){ this.res.send(['BOSS系统','ver:0.01','author:BYTS','date:2014-1-1']); }; controller.prototype.action_login=function(){ //渲染页面就这么简单 this.res.render("site/login",{ "title":"BOSS系统" //变量 }); }; exports.controller = controller;
在views目录增加两个子目录 ,layouts(布局用),site(所有site的子页面都放这里)
然后新建三个页面
(1)、/views/layouts/header.ejs
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <title> <%=title%> </title> </head> <body>
(2)、/views/layouts/footer.ejs
</body> </html>
(3)、/views/site/login.ejs
<% include ../layouts/header.ejs %> <h1><%=title%></h1> <form> 用户:<input type="text" name="user_name" /><br/> 密码:<input type="text" name="user_psw" /><br/> <input type="submit" value="提交" /> </form> <% include ../layouts/footer.ejs %>
访问http://www.boss.xx/site/login
现在不管界面简陋,先实现功能,接着我们来完成重要的数据库部分,数据对象
相关文章推荐
- ubuntu 13.10 安装inode客户端
- Remove Nth Node From End of List
- Swap Nodes in Pairs
- Reverse Nodes in k-Group
- [NodeJS] Node.js 编码转换
- sys node for g sensor KXT_9
- 技术栈的选择:从Groupon转向Node.js、淘宝去IOE谈起
- 从零开始node.js入门项目(二)
- 从零开始node.js入门项目(一)
- CHD4B1(hadoop-0.23)实现NameNode HA安装配置
- [leet code] Populating Next Right Pointers in Each Node
- 关于新学 node js 从实例出发。
- Leetcode: Swap Nodes in Pairs
- Dom树:(Node)结点树
- struct inode 和 struct file
- win7搭建ghost开发所需环境
- The method getTextContent() is undefined for the type Node 的解决办法(eclipse)
- node.js
- Populating Next Right Pointers in Each Node
- osg demo19 回调,使一个node来回动