什么是Clouda?

Clouda是百度的一款开源NodeJs轻应用框架,拥有百度强大的技术支持,实现快速开发、优化SEO、易部署等特性,提供简单易用的依赖管理模块化开发环境。

详细信息,请猛击Clouda主页:http://cloudajs.org

安装和使用Clouda

安装Clouda

Clouda是基于node.js的Webapp开发框架,在使用Clouda时需要安装node.jsMongoDB,如果您没有安装请参考本文档环境搭建部分。

使用下面命令安装Clouda

npm install -g sumeru

使用Clouda创建工程

sumeru init ./myproject

运行Clouda

在运行Clouda前需要启动MongoDB,如何启动MongoDB请参考本文档环境搭建部分。

cd myproject
sumeru start

环境搭建

安装node.js

Clouda是基于node.js的开发框架,所以我们首先需要安装node.js

  • 下载node.js,地址:http://nodejs.org/download/

  • 安装node.js

安装MongoDB

在本地Clouda使用mongoDB作为数据库,按照下面的步骤安装并启动MongoDB

  • 下载mongoDB,地址:http://nodejs.org/download/

  • 解压下载的文件夹,进入解压后的目录,在目录下创建"data"目录,并在创建的"data"目录下创建"db"文件夹

  • 进入根目录下的bin/,使用下面的命令启动MongoDB

    sudo ./mongod -dbpath ../data/db

注意:在运行Clouda应用前必须启动MongoDB

现在开发一款基于Clouda框架的RSS阅读器实例。


首先,我们按照官方的步骤,安装好Clouda和MongoDB。

然后我们进入到app/controler/package.js 编辑该文件:

sumeru.packages('RSSreader.js'
)

这里定义了一个RSSReader的控制器(实际上是文件,但一般来说要从文件名中可以读取该文件的用途)。

接着我们补充这个RSSreader.js的实际内容:

sumeru.router.add({pattern: '/RSS',action: 'App.RSSReaderAction'});
//上面的配置,pattern 指定了一个路由的路径匹配,意思就是,访问你应用的/RSS/后面的位置,路由就被匹配到了。
//但匹配后做什么?别急,action 指定了一个控制器:App.RSSReaderAction,这个控制器就是用来执行相应的动作,如下。
App.RSSReaderAction = sumeru.controller.create(function(env, session) {//定义试图文件名var view = 'html';var processDoc = function(doc){//文档处理方法var html = '';var xml = $.parseXML(doc);var $doc = $(doc);var items = xml.getElementsByTagName('item');$.each(items,function(index,element){var title = this.getElementsByTagName('title')[0];var link = this.getElementsByTagName('link')[0];var h3 = '<h3 style="border-left:solid 3px #99CCFF;padding:10px 5px;"><a style="color:#333;" href="'+link.textContent+'" target="_blank">'+title.textContent+'</a></h3>';var description = '<div style="background:#EEE;padding:5px;" class="f-rrs-item-content">'+this.getElementsByTagName('description')[0].textContent+'</div>';html+='<li>'+h3+description+'</li>';});return '<ul style="list-style:none;">'+html+'</ul>';}var getData = function() {//这里负责获取并解释从路由器传递过来的参数(我们这里需要RSS网址)var argLength = env.arguments.length;var url = '';console.log('arg length -> '+argLength);for(var i=1;i<argLength;++i){var arg = env.arguments[i]if(arg=='http:'||arg=='https:')arg+='//';else if(i!=argLength-1)arg+='/';url+=arg;}console.log('url -> '+url);//分析完之后我们要使用subscribe去做处理//每个subscribe都要对应一个publishenv.subscribe('pubhtml', url , function(newsCollection){//console.log(ewsCollection.getData());var obj = newsCollection.getData()[0];//使用文档处理方法,返回一条压缩过的html代码var content = processDoc(obj['body']);//session与 block 进行数据绑定session.bind('htmlBlock', {'htmlContent' : content});});}env.onload = function(){//onload 事件是整个Controler生命周期中第一个事件,用于进行数据处理return [getData];}env.onready = function(){//onready 是 Controler生命周期的第三个事件,在这个环节代表View已经被渲染完成,可以做里面的DOM操作}env.onrender = function(doRender){//onrender 是 Controler生命周期的第二个事件,这个环节是开始渲染ViewdoRender(view, ['rotate','left']);};
});

如果你阅读完代码后,你会发现一个在网页前端上最常用的字符变量$,这个一般是在jQuery使用最多(很多热门的JS库都占用$符号,不只是jQuery),在这里我习惯了使用jquery去操作DOM,所以,我要实现引用jQuery的库,否则上面的代码根本不能正常执行。

首先我们到app下建立一个jslib的文件夹,然后将jQuery.js放到里面(如果不知道怎么获取jQuery.js的话,请自行百度。。。)

接着,我们在app下找到一个叫package.js(是不是很熟悉,没错,你在controller里头也见过同样的文件,所以,你可以发现,package.js就是整个框架的配置文件,而且是不同层面下都需要一个。)

package.js:

sumeru.packages('config','controller','model','library','jslib/jquery.js'
);

注意,前面4个是框架必须导入的库,最后一个才是我自行添加的。jslib就是刚才我在app下自行创建的文件夹

,当然,如果你喜欢你可以叫他jsFiles,这个纯属个人喜好。另外需要提及的是,如果你在里面要使用其他各种的JS框架库,你可以在后面继续添加jslib/xxx.js,也有一个一部到位的方法,就是直接改成jslib,那么,Clouda就会把整个文件夹加载进来,读取里面一个叫package.js(路径为:jslib/package.js),所以这个时候你要相应配置一下jslib/package.js,详细配置入下:

app/package.js:

sumeru.packages('config','controller','model','library','jslib'
);

app/libs/package.js:

sumeru.packages('jquery.js'
);

简而言之,如果你不想你的配置列表被配置得太长太难看(当你需要管理的模块结构文件非常大和非常多的时候!),你可以尝试使用以上的方式去配置每一个文件的依赖关系,这样,妈妈再也不用担心我的配置表太凌乱了:-)

还有一个问题需要提及一下,千万不要在package.js文件下写注释或者其他js代码,哪怕是console.log('加载文件');

我不太清楚是Nodejs上的约定还是Clouda在约定(我个人也是刚开始接触Nodejs),我也没见过其他nodejs的package.js配置文件存在这些。反正就是,千万别做这样的蠢事就对了,否则,出错了你也不知道是什么问题(因为这个绝对不是js文件这么简单)。

继续我们的RSS阅读器,回顾这个Controller/RSSreader.js控制器

getData Fn 开始:

var getData = function() {//这里负责获取并解释从路由器传递过来的参数(我们这里需要RSS网址)var argLength = env.arguments.length;var url = '';console.log('arg length -> '+argLength);for(var i=1;i<argLength;++i){var arg = env.arguments[i]if(arg=='http:'||arg=='https:')arg+='//';else if(i!=argLength-1)arg+='/';url+=arg;}console.log('url -> '+url);//分析完之后我们要使用subscribe去做处理//每个subscribe都要对应一个publishenv.subscribe('pubhtml', url , function(newsCollection){//console.log(ewsCollection.getData());var obj = newsCollection.getData()[0];//使用文档处理方法,返回一条压缩过的html代码var content = processDoc(obj['body']);//session与 block 进行数据绑定session.bind('htmlBlock', {'htmlContent' : content});});

通过env对象,可以获取arguments,arguments的大致内容是路由器匹配后的地址信息"RSS/xx/xxx/xx",

还是用/符号分割的每一个占一个位置,所形成的数组,而arguments[0]则被"RSS"所占用,所以这里我们从下标1开始索引到最后一个参数用来形成一个Url地址

(RSS阅读源的URL,比如:http://atalasii.com/rss 。在程序中的arguments获取处理则是:arguments[1]:'http',arguments[2]:'atalasii.com',arguments[3]:'rss')。

所以,我设计当程序完整被访问的时候,实际使用的形式是:http://localhost:8080/index.html/RSS/rss源URL地址

以上面的URL例子,则是:http://localhost:8080/index.html/RSS/http://atalasii.com/rss

这里的https://atalasii.com/rss就是完整的RSS阅读源地址,只需要加在RSS后面就可以了,路由器通过RSS匹配到后自动找到相应的控制器,而我们设定的控制器将解释后面的参数,形成合法的URL,稍后将介绍如何读取这个URL内容

subscribe / publish

Clouda提供subscribe(订阅)与publish(发布)的API,提供数据处理,也就是接着上文,我们获取了URL后要使用这套API进行数据获取和展示

env.subscribe('pubhtml', url , function(newsCollection){//console.log(ewsCollection.getData());var obj = newsCollection.getData()[0];//使用文档处理方法,返回一条压缩过的html代码var content = processDoc(obj['body']);//session与 block 进行数据绑定session.bind('htmlBlock', {'htmlContent' : content});});

上面的代码,做了一个简单的订阅服务,首先,url已经被拼接完成了,剩下的就是使用订阅服务,将url发到publish去处理。

Next step -> 我们创建一个publish去获取数据

publish主要用于作为获取后台数据库的数据,然后提供给subscribe,所以这两个API是成对使用的

不过在这里由于RSS里的内容并不存储在我们的数据中,而是一个外部的API,所以,这个时候我们在这里还要做一个外部数据的扩展,详情步骤如下:

在app下的publish目录里(如果没有请自行新建)创建一个pubhtml.js:

module.exports = function(fw){fw.publish('html','pubhtml',function(url,callback){var collection = this;collection.extfind('feedContent',url,callback);});}

这里的pubhtml文件的命名与控制器(RSSreader.js)里头的env.subscribe('pubhtml'...是一致的,意思是subscribe(订阅)名字叫(pubhtml)的publish(发布)

在pubhtml.js里头,里面的url,就是从RSSreader.js传递进来的参数,现在要在获取外部信息,所以我们使用了publish external


publish external 官方的解释就是:实现了三方数据同步的方法,用来满足从三方网站/三方接口获取和同步数据的需求。

我们在同目录下再创建一个js文件 externalConfig.js:

/*** 获取第三方数据信息,由开发者自定义*/
function runnable(){var iconv = require('iconv-lite');//{Object} config是所有三方publish配置的容器var config = {};config['feedContent'] = {//{String} uniqueColumn为三方数据唯一标识//uniqueColumn : "name",//method:GET/POST,暂不支持PUT和DELETE方法,默认请求方式为GETmethod:"POST",//{Function} fetchUrl的参数就是订阅时发起的参数,返回值为pubext所抓取的url地址fetchUrl : function(url){console.log(url);return url;//'http://segmentfault.com/feeds';},//{Function} resolve方法作用是将抓取回来的原始数据(originData)转化成为符合Model定义的数据(resolved)resolve : function(originData){console.log(originData);var resolved = {head:'2',body:originData};return resolved;},//{Number} fetchInterval为可选参数,用来指定抓取时间间隔,单位为ms//fetchInterval : 60 * 1000,//{Boolean} buffer为可选参数,值为true时表示获取原始Buffer,否则获取原始数据字符串buffer : false}//最后需要声明此模块为归属为'external'return {type : 'external',config : config}}module.exports = runnable;

上述代码是改自官方API手册的代码,其中第10行就定义了这个external的名字"feedContent",然后根据publish的collection.extfind方法匹配名字和传递url参数

collection.extfind('feedContent',url,callback);

而这里定义的resolve方法取抓取url地址源的数据,并且通过简单的封装处理,返回给上层(publish -> Controler),所以最终发现Controler(RSSreader.js)里头的这段代码是如何处理这个被封装的对象:

env.subscribe('pubhtml', url , function(newsCollection){//console.log(ewsCollection.getData());var obj = newsCollection.getData()[0];//使用文档处理方法,返回一条压缩过的html代码var content = processDoc(obj['body']);//session与 block 进行数据绑定session.bind('htmlBlock', {'htmlContent' : content});});

最后,使用session对象(session对象是当前页面的会话对象,每一个打开该应用的都会有独立的session对象)来进行数据绑定联动更新,最后,这个应用就算完成了。

按照以上步骤创建好应用好,你只需要在浏览器输入:http://localhost:8080/index.html/RSS/http://atalasii.com/rss   就可以访问数据源是http://atalasii.com/rss的RSS信息,一个相对简陋的阅读器。

当然,你也可以启动debug模式,只需要将index.html改为debug.html,然后打开控制台(不知道如何呼出控制台的,请先面壁),你就可以看到各种调试信息,方便你开发应用!

最后公开这个小DEMO的源码Github地址:https://github.com/forfuns/Clouda_RSS_Reader

(注意:由于mongodb比较大无法上传到github,请无视mongodb下的所有东西,或者删除掉另行创建mongodb)

最后的最后 :-) 说下对使用这个框架的感受:

CloudaJs 是一个非常易用的NodeJs框架,正如官方所描述的一样可以实时更新数据,使用Socket实现零延迟;高兼容性,可以使用各种前端JS的框架(比如目前我使用的 jQuery),不需要入侵其他框架库代码;易用快速入门,语法精炼简单,API清晰,会JS你就可以前后端兼顾。配合百度自身搜索优势,一键托管还有SEO优化随手可得。

总体来说,是一个免费强大,居家旅行必备的轻应用框架。

2013-12-24 补充:

部署到BAE上,附带CSDN的RSS阅读地址,总体效果预览请猛击下面(界面什么的暂且无视吧,能阅读就好!)

http://onlinerssreader.duapp.com/index.html/RSS/http://www.csdn.net/article/rss_lastnews

使用百度Clouda框架创建RSS阅读器应用相关推荐

  1. 如何在JavaScript中创建RSS阅读器应用程序

    RSS(真正简单的联合组织)是一种在线发布者用来将其内容联合到其他网站和服务的标准化格式. RSS文档 (也称为feed )是一种XML文档 ,其中包含发布者希望分发的内容. 几乎所有在线新闻网站和博 ...

  2. RSS阅读器使用:ROME,Spring MVC,嵌入式Jetty

    在这篇文章中,我将展示一些创建Spring Web应用程序的准则,使用Jetty以及使用名为ROME的外部库运行RSS来运行它. 一般 我最近创建了一个示例Web应用程序,充当RSS阅读器. 我想检查 ...

  3. 基于ASP.NET AJAX技术开发在线RSS阅读器(下篇)

    五.逻辑层设计 (一)添加RSS频道 在展开真正的逻辑层设计之前,先让我们简单地浏览一下下面的草图4.图4展示了我对于两个重要ASP.NET AJAX客户端控件-ListView和DataSource ...

  4. Web版RSS阅读器(四)——定制自己的Rss解析库myrsslib4j

    在上篇博文<Web版RSS阅读器(三)--解析在线Rss订阅>中,已经提到了遇到的问题,这里再详细说一下. 在解析rss格式的订阅时,遇到的最主要的问题是,出现了"Server ...

  5. Feeder 一款 Mac 上的 RSS 阅读器,更优雅地跟踪最新的新闻和博客文章

    Feeder 一款 Mac 上的 RSS 阅读器,更优雅地跟踪最新的新闻和博客文章 Feeder 是一款 Mac 上的 RSS 阅读器,它可以帮助用户轻松地订阅和管理 RSS 源,让用户可以轻松地跟踪 ...

  6. 一步一步学Silverlight 2系列(18):综合实例之RSS阅读器

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  7. 用JSP实现基于Web的RSS阅读器

    2019独角兽企业重金招聘Python工程师标准>>> 一 RSS介绍 根据维基百科(http://zh.wikipedia.org/wiki/RSS)的定义,"RSS是一 ...

  8. PHP rss聚合,利用PHP和AJAX创建RSS聚合器

    下载本文示例代码 想象使用一个简单HTML文件来把一个请求发送到一个服务器端脚本,收到一个基于该请求的定制XML文件,然后把它显示给用户而几乎不需要刷新浏览器!本文作者将同你一起探讨怎样在普通Web应 ...

  9. UWP 推荐 - 限时免费的RSS阅读器《RSS 追踪》登录 Windows 10

    文/云之幻 前不久,博客作者 Bravo Yeung 写了一篇还算略受欢迎的关于 RSS 的文章 .Net开发者必知的技术类RSS订阅指南. RSS 现在用的人很少了,而且就算是我,也不过是在一周前才 ...

最新文章

  1. flux服务器推消息,在Spring WebFlux响应式处理程序中发送JMS消息:它是否阻塞?
  2. python代码壁纸-爬虫 抓取王者荣耀所有英雄皮肤高清壁纸+超强注释
  3. SM35/BDC Record / Log 导出
  4. 通信控件MSComm使用详解
  5. jfinal文件上传
  6. 10张图22段代码,万字长文带你搞懂虚拟内存模型和malloc内部原理
  7. SpringBoot2.6.1 elasticsearch7.1.5 Vue
  8. Android开发之Scroller
  9. mysql与sqlyog连接_如何用sqlyog实现远程连接mysql
  10. ios icon尺寸问题
  11. java开发环境有哪些_Java学习开发环境配置大全
  12. 地区编码(定位中用到的编码)
  13. Web网页——留言板功能
  14. html5中框架怎么写,html框架布局模板
  15. 谷歌浏览器 无法翻译此网页的解决方法
  16. 与你,预约一个来生的相逢
  17. 微信微粒贷开通什么条件?微粒贷开通方法及流程
  18. 存在为退还的延长失保金支付记录,需退还后才能就业登记
  19. 百度天气预报API的使用(java版本)
  20. Magento 手机支付 (支付宝无线支付)

热门文章

  1. 具有连续调制光栅区域的光波导优化
  2. linux 存储映射lun 给_LINUX系统下添加映射存储LUN(无需重启)
  3. Java 8除不尽的数
  4. 企业级呼叫中心 如何构建?
  5. qq音乐登录参数详细分析及密码加密最新版
  6. Ubuntu安装ROS详细教程
  7. 定时开关机-Android4.4/6.0
  8. laravel阿里SDK对接
  9. 开发常用英语单词表格
  10. 【杂记】火狐浏览器主页被2345恶意篡改解决方法