您的位置:首页 > Web前端 > Node.js

从零开始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.js

var 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



现在不管界面简陋,先实现功能,接着我们来完成重要的数据库部分,数据对象
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: