最近学习nodejs,刚看完BYVoid大大的《Node.js开发指南》,有点手痒,摆弄了一番express,但还是觉得有些复杂,刚好看到百度也出了一个node的web框架clouda,号称开发简单,本着学习的态度,上手试用了一下,下面就把试用的过程给大家分享分享。
clouda使用的是MongoDB数据库,它的数据存储的形式是bjson,是json的一种扩展,操作命令也和javascript函数挺像,有js基础的可以直接上手。
要使用clouda需要下载node.js和MongoDB,并且把两者运行起来,目前clouda官方还没有一个集成环境,它自己的包也是在npm里面,包名叫做sumeru,我是在win7下面安装,要run起来,准备工作还是不少的。
安装和启动
下载node.js:http://nodejs.org/download/
下载MongoDB:http://www.mongodb.org/downloads
安装npm包管理器:可参考 http://www.cnblogs.com/seanlv/archive/2011/11/22/2258716.html
安装clouda:nodejs和npm都安装好后,在命令行里输入如下命令
npm install -g sumeru
创建clouda工程:这里就创建一个名为“study01”的工程
sumeru init ./study01
启动MongoDB:首先在MongoDB目录下建立data文件夹,然后在data文件夹里建立db文件夹,然后另开一个命令行窗口,进入MongoDB下的bin目录,输入命令
mongod.exe -dbpath ../data/db
运行Clouda:在命令行进入study01目标,输入命令
sumeru start
上面的每一步都需要保证无误,特别是npm的安装,安装完成后务必用npm -v命令测试一下。
如果没有错误的话,会得到如下图:
这时候,可以在浏览器里输入:
localhost:8080/debug.html/itworks
如果出现“Welcome to sumeru!”则说明我们的clouda工程已经安装成功。
第一个项目
关于clouda项目下面的目录和文件都有什么作用,大家可以上官网http://cloudajs.org/ 上去查文档,这里就不多说了。
下面我们开始建立一个项目试试,这个项目的目的是抓取一个网站的一部分内容,并且将其显示出来。
clouda使用pubsub的事件处理方式来实现双向数据绑定,在前端则用js模板引擎handlebars来实时刷新UI,这就是clouda实时性的由来,当然其内还有很多的技术细节来实现云到端的数据统一。
clouda是按照MVC模式来运作的,所以每一个项目都必须分别定义M、V、C,对于我们的这个小项目,分别定义如下:
Model:在study01目录下的app/model里,建立news.js:
Model.news = function(exports){ exports.config = { fields : [ {name: 'news', type: 'text'} ] }; };
即定义数据模型为text类型的content,然后修改同目录下面的package.js:
sumeru.packages( 'news.js' )
Controller:这里我们要建立pubsub模型,然后还要管理场景的生命周期:
首先建立pub,在app/publish/下,建立pubnews.js:
module.exports = function(fw){ fw.publish('news','pubnews',function(callback){ var collection = this; collection.extfind('pubnews',callback); }); }
我们还需要抓取第三方网站内容,然后将其保存到model中,这里利用clouda提供的external方法,相当于其他环境中的curl或者fetchurl,抓什么网站呢?就抓51cto移动开发首页吧,不过这里遇到一个问题,抓取出来的内容是乱码,原来nodejs只支持utf-8,而目标网页是gb2312编码的,幸好npm里有转码插件,那么赶紧装上吧:
npm install iconv-lite
然后在同目录下建立externalConfig.js:
/** * 获取第三方数据信息,由开发者自定义 */ function runnable(){ //使用转码插件iconv-lite var iconv = require('iconv-lite'); //{Object} config是所有三方publish配置的容器 var config = {}; config['pubnews'] = { //{String} uniqueColumn为三方数据唯一标识 uniqueColumn : "mobile51CTO", //method:GET/POST,暂不支持PUT和DELETE方法,默认请求方式为GET method:"POST", //{Function} fetchUrl的参数就是订阅时发起的参数,返回值为pubext所抓取的url地址 fetchUrl : function(/** arg1, arg2, arg3 */){ return 'http://mobile.51cto.com'; }, //{Function} resolve方法作用是将抓取回来的原始数据(originData)转化成为符合Model定义的数据(resolved) resolve : function(originData){ decodeData = iconv.decode(originData,'gb2312'); var hotnewsRegex = /<ul class="list01">([\W\w]*?)<\/div>/; var hotnews = decodeData.match(hotnewsRegex)[1]; var resolved = { hotnews: hotnews } return resolved; }, //{Number} fetchInterval为可选参数,用来指定抓取时间间隔,单位为ms fetchInterval : 15 * 60 * 1000, //{Boolean} buffer为可选参数,值为true时表示获取原始Buffer,否则获取原始数据字符串 buffer : true } //最后需要声明此模块为归属为'external' return { type : 'external', config : config } } module.exports = runnable;
然后建立subscribe,并进行场景控制的生命周期管理,都在app/controller/下面,建立news.js:
sumeru.router.add( { pattern: '/news', action: 'App.news' } ); sumeru.router.setDefault('App.news'); App.news = sumeru.controller.create(function(env, session){ var view = 'news'; var getNews = function(){ session.news = env.subscribe('pubnews', function(newsCollection){ var obj = newsCollection.getData()[0]; session.bind('newsBlock', { 'hotNews' : obj['hotnews'] }); }); }; env.onload = function(){ return [getNews]; } env.onrender = function(doRender){ doRender(view, ['push','left']); }; });
然后同样修改同目录下的package.js:
sumeru.packages( 'itworks.js', 'news.js' )
View:这里就是显示了,在app/view/下建立news.html:
<!DOCTYPE html> <html lang="en-US"> <head> <meta http-equiv="content-type" content="text/html; charset=gb2312" /> <title>51CTO移动开发热点新闻</title> </head> <body> <h1>Top news</h1> <block tpl-id="newsBlock"> <div> {{{hotNews}}} </div> </block> </body> </html>
代码部分到这里就完成了,然后重新启动MongoDB和Clouda,然后在浏览器中输入
localhost:8080/debug.html/news
如果出现如下画面,则说明这个小项目已经成功了。
总结:
clouda的确是比较简单的,不过门槛也还存在,零基础来玩这个东西是不可能的,另外因为javascript至今没有一个好的开发调试环境,特别在node.js中调试难度更是倍增,因此用clouda开发主要要克服这些方面的困难。
本文出自 “pockry的博客” 博客,转载请与作者联系!