如何使用Node.js实现简易MVC框架

JavaScript013

如何使用Node.js实现简易MVC框架,第1张

MVC模式学习之MVC解释:

Model(模型)——View(视图)——Controller(控制器)

1、视图和控制器都依赖于模型;

2、模型相对独立,可以自己的调试和使用

3、在胖客户端程序中,视图和控制器的分离是次要的。

4、在Web程序中可以将视图理解为浏览器,服务器端组件为控制器,模型即为业务逻辑模块

MVC的处理过程:

首先控制器接收用户的请求,并决定应该调用哪个模型来进行处理,然后模型用业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图格式化模型返回的数据,并通过表示层呈现给用户。

Angular.js 的wed MVC框架:

目前的前端MVC 框架有很多,如Angular.js,Backbone.js,Javascript MVC,Knockout.js等。虽然都是基于MVC,但是每个框架都有自己处理问题的方法,下面简要分析Angular.js的特点以及适用范围: AngularJS是Google推出的开源的JavaScript MV*(MVW、MVVM、MVC)框架,目前由Google维护。AngularJS弥补了HTML在构建应用方面的不足,其通过使用标识符(directives)结构,来扩展Web应用中的HTML词汇,使开发者可以使用HTML来声明动态内容,从而使得Web开发和测试工作变得更加容易。

使用AngularJS,Model直接与UI视图绑定,Model与UI视图的关系,通过directive封装,AngularJS内置的通用directive,就能实现大部分操作了,也就是说,基本不必关心Model与UI视图的关系,直接操作Model就行了,UI视图自动更新。而Model数据验证、与服务器端的数据交互都是非常简单而自由的。

AngularJS的directive,你输入特定数据,他就能输出相应UI视图,这样的directive可以变成了一个html通用组件,比如文章编辑器组件、分页导航组件、madal组件等,在不同应用中可以直接拿来用,减少重复开发。

用angular.js,写UI视图就是写正常的HTML/CSS,写逻辑控制代码就是用JavaScript操控数据(不是DOM),不同的就是增加了directive,实现DOM与数据的互动,如上所述,directive是通用组件。AngularJS只是定义了一个环境和一个数据与视图交互的机制,并提供了若干通用组件和服务,所以AngularJS开发很简单,很高效,很“原生态”。

写了这么多AngularJS代码,可以说我对AngularJS了解比较深入了。Backbone也是一个很热门的JS框架,我通读了一下它的API文档,大概了解了他的运行机制。

Backbone很精巧,很强大。但对比AngularJS,我说说我看到的Backbone的缺点,由于接触时间短,可能会存在误解,见谅。

Backbone的Model把服务器端的数据模型映射到浏览器端,绑定数据验证机制,并与相应的REST操作绑定,这样每个数据模型都变成了独立体,方便REST操作,却限制REST的灵活性。比如我要将10个todo批量标记成已完成,它会发出10个REST请求。

Backbone的Model没有与UI视图数据绑定,而是需要在View中自行操作DOM来更新或读取UI数据,这点很奇怪。AngularJS与此相反,Model直接与UI视图绑定,Model与UI视图的关系,通过directive封装,AngularJS内置的通用directive,就能实现大部分操作了,也就是说,基本不必关心Model与UI视图的关系,直接操作Model就行了,UI视图自动更新。而Model数据验证、与服务器端的数据交互都是非常简单而自由的。

AngularJS的directive,你输入特定数据,他就能输出相应UI视图,这样的directive可以变成了一个html通用组件,比如文章编辑器组件、分页导航组件、madal组件等,在不同应用中可以直接拿来用,减少重复开发。我想,Backbone大概很难实现这样的通用组件。

Backbone的View没有把html与JavaScript解耦,要控制UI视图,实际上就是用JavaScript控制DOM,或者通过第三方模板引擎控制HTML字符串,而这些,都需要程序员在代码中用JavaScript自行实现。

AngularJS不同,写UI视图就是写正常的HTML/CSS,写逻辑控制代码就是用JavaScript操控数据(不是DOM),不同的就是增加了directive,实现DOM与数据的互动,如上所述,directive是通用组件。AngularJS只是定义了一个环境和一个数据与视图交互的机制,并提供了若干通用组件和服务,所以AngularJS开发很简单,很高效,很“原生态”。

虽然我没有真正写过桌面应用程序,但我觉得AngularJS的理念就是把WEB当作应用程序来写——Web App。反观Backbone,对于数据与UI视图的互动并没有大的改进,仅仅提供了数据变更事件通知,它侧重于REST数据交互了,而REST数据交互本来是很容易处理的。

本框架适合使用NodeJs进行web开发的MVC框架模式,本框架使用了express框架作为nodejs的web开发支撑,使用mysql作为数据库开发源,下面我们就简单的介绍如何利用本框架进行一个简单的web应用开发。当然本框架并非官方,也并非专业设计,希望开发者共同来把本框架设计好,以便我们可以在国内实现一个NodeJs的Web开发框架。

一、项目文件夹介绍

项目文件夹主要是根据传统的MVC设计模式,设计出来的框架。

enter image description here

二、 入口文件介绍

本框架的入口文件为index.js,该入口你可以添加多种全局静态变量,例如你所需要的各个文件夹路径,以及一些模块。

举例如下:

//========================全局变量定义===============================

global.BASE_DIR = __dirname

global.APP = global.BASE_DIR + "/application/"

global.CON = global.APP + "/controller/"

global.CORE = global.APP + "/core/"

global.MODEL= global.APP + "/model/"

global.CONF = global.BASE_DIR + "/conf/"

global.log = global.BASE_DIR + "/log/"

global.PUBLIC = global.BASE_DIR + "/public/"

global.VIEW = global.BASE_DIR + "/view/"

/**

modules引入

*/

global.express = require(‘express’)

global.sio = require(‘socket.io’)

global.fs=require(‘fs’)

global.path = require(‘path’)

global.url = require(‘url’)

global.parseCookie = require(‘connect’).utils.parseCookie

global.MemoryStore = require(‘./node_modules/connect/lib/middleware/session/memory’)

global.Session = require(‘./node_modules/connect/lib/middleware/session/session’)

global.sys = require(‘util’)

代码2-1:index.js

在index.js中你需要将你所有的文件夹路径、模块使用全局变量进行替换,该方法的优势在于,避免用户在编码中引入过长的文件路径,只需要使用简单的变量进行替换。

urlResolve = require(CORE + “url_resolve”)

urlResolve.getActionInfo()

代码:2-2:路由处理逻辑

本代码包含进逻辑处理类,同时应用逻辑处理类中的getActionInfo方法,创建服务器,并且处理url请求逻辑。

三、 路由处理逻辑

主要有六个方法,其中的getActionInfo是exports,其他方法均为私有方法。

exports.getActionInfo = function(){

systemConfig()

app.get('/:key', function(req, res){

callUrlRequest(req, res)

})

app.post('/:key', function(req, res){

callUrlRequest(req, res)

})

listenPort()

}

function callUrlRequest(req, res){

var routerMsg = getUrlConf()

var key = req.params.key

var session = checkSession(req, key)

if(key == "favicon.ico"){return}

if(session == 0){

res.redirect('/index')

return

}

console.log("[key:"+ key +"] " + "[class:" + routerMsg[key].cla + "] " + "[controller:" + routerMsg[key].fun +"]")

require(CON + routerMsg[key].con)

var controllerObj = eval("new " + routerMsg[key].cla)

controllerObj.init(req, res)

controllerObj[routerMsg[key].fun].call()

}

代码2-3:路由处理getActionInfo

SystemConfig是配置express框架的相应数据,配置静态文件夹以及express框架的相应配置数据。之后添加两种url请求方式,分别是get和post方法,由于两种方法请求资源的路由处理都是一样的,因此使用callUrlRequest来处理。

callUrlRequest 获取路由配置文件信息getUrlConf;

2、获取当前访问的key值,根据key值得到相应的配置信息,配置文件可以展示如下:

"test": {

"con" : "test",

"cla" : "test",

"fun" :"test"

},

"favicon.ico" : {

"con" : "",

"cla" : "",

"fun" : ""

},

"login" : {

"con" : "index_controller",

"cla" : "IndexController",

"fun" : "loginAct"

},

"index" : {

"con" : "index_controller",

"cla" : "IndexController",

"fun" : "loginPageAct"

},

"loginS" : {

"con" : "index_controller",

"cla" : "IndexController",

"fun" : "toMainPageAct"

}

}

代码2-4:配置文件信息

如果当前key为test那么我们就可以得到相应的controller、class和function。同时因为nodejs服务器每次请求数据的时候都会加入favicon.ico,因此在代码中我们需要将其剔除。对于checkSession就是验证登录信息。

3. 得到controller、class和function,首先require相应的controller,然后使用eval来new相应对象,使用controllerObj[routerMsg[key].fun].call()该方法进行调用。(本部分处理,涉及到一个JavaScript的小技巧,如何对一个字符串进行new,同时调用一个对象的方法,该方法名为字符串变量)

4. 最后就是listenPort()进行监听事件,也是服务器开始启动。这样一个基本的路由处理就完成实现了。

**四、 数据层实现**

本系统数据层基类是在core文件夹下的base_model.js,该类主要包含数据库的一般方法,主要含有数据库链接、数据库操作基本方法add、update、deleteItem、query、select等,具体实现方式,就不细讲。

BaseModel为基类,其他对应于相应的表的类都继承来自BaseModel基类

继承方法使用JavaScript的原型继承:

IndexController.prototype = new BaseController()

global.IndexController = IndexController

**五、 逻辑层实现**

类同于数据层的实现方法,其继承都是来自于基类BaseController,BaseController现只包含三个方法:init、displayHtml、displayJade。

**六、 代码规范

** 本框架不要求开发者是如何去定义代码规范,但本框架实现的代码规范是如下:

变量命名:私有变量统一使用”_name”,全局变量使用大写”VIEW”,简单变量请使用骆驼峰”myName”

方法命名:所有方法请使用骆驼峰”getUrlRequest”

类命名:统一使用首字母大写骆驼峰”BaseController”

文件命名:统一使用下划线分割,类使用下划线分割base_controller.js

总结:整体上就可以实现一个MVC开发的MyWeb框架,其中的方法以及实现都还是处于稚嫩期,希望有开发者愿意加入,并且能够团队合作开发出我们国内优秀的NodeJs的MVC框架。