基于meteor开发的
Meteor是一个新JavaScript框架,旨在自动化和简化实时运行的Web应用程序的开发。 它使用称为分布式数据协议(DDP)的协议处理实时通信,使用WebSocket的新型浏览器和使用异步JavaScript + XML(Ajax)长轮询的较旧的浏览器均支持该协议。 在这两种情况下,浏览器到服务器的通信都是透明的。
DDP协议旨在与JavaScript序列化对象表示法(JSON)文档的集合一起使用,从而使创建,更新,删除,查询以及查看JSON文档变得容易。 由于DDP是开放源代码协议,因此可以想象将其连接到您需要的任何客户端或数据存储。 开箱即用,它适用于MongoDB。
实际上,Meteor提供了两个MongoDB数据库:客户端缓存数据库和服务器上的MongoDB数据库。 当用户更改某些数据时(例如,单击“ 保存”) ,浏览器中运行JavaScript代码将更新本地MongoDB中的相应数据库条目,然后向服务器发出DDP请求。 该代码立即执行,就好像该操作成功完成了,因为它不需要等待服务器回复。 同时,服务器在后台更新。 如果服务器操作失败或返回意外结果,则客户端JavaScript代码将根据从服务器新返回的数据立即重新调整。 这种调整称为等待时间补偿 ,可为用户提供额外的感知速度。
甚至Meteor的模板系统也经过专门设计,可简化实时通信。 在大多数Web框架中,您可以轻松地将超文本标记语言(HTML)或等效于HTML的标记(例如HTML抽象标记语言(Haml))与代码混合在一起。 这使您可以轻松地将数据库中的动态值插入发送给用户的页面中。 之后,您负责将一个系统安装到位,以观察数据的更改,然后更新您的标记。 但是,Meteor中的模板系统旨在记录从模板访问哪些数据,并在基础数据发生更改时自动设置回调以更改HTML,从而使实时模板变得轻松快捷。
流星的模板功能可以使各种实时应用程序更容易编写。 例如,假设您要创建一个站点,用户可以在其中输入链接(即统一资源定位符(URL))并对其进行投票或上下投票,而赢得人气竞赛的URL则显示在列表的顶部。 使用Meteor,您可以轻松,实时地编写这样的应用程序,以便用户可以看到其他用户的65票。
要安装Meteor,请在Linux®或MacOS®X终端中输入清单1中所示的代码。 流星不支持Microsoft®Windows®。
curl https://install.meteor.com > install_meteor.sh
chmod u+x install_meteor.sh
./install_meteor.sh
现在您可以创建一个新项目。
meteor
命令使用Meteor所需的所有操作来自动化创建新项目的过程。 键入清单2中所示的命令,以创建一个名为realtime_links的项目。
meteor realtime_links
cd realtime_links
流星创建一个目录,其中包含HTML文件,JavaScript文件和级联样式表(CSS)文件。 最后一个是标准CSS文件,但是前两个值得讨论。 您可以从“ 下载”部分下载 realtime_links.html和realtime_links.js文件的完整版本。
清单3显示了realtime_links.html文件的标题和正文片段。
Realtime Links Demo
{{> header }}
{{> link_list }}
{{> add_new_link }}
如您所见,HTML模板的开头很简单。 您无需担心包括BODY
标记, DOCTYPE
声明,甚至JavaScript和CSS文件。 流星为您处理所有这些。 有关MeteorJavaScript和CSS捆绑的更多信息,请参阅参考资料,获取指向Meteor网站的链接。
{{>
语法的意思是“呈现此模板”。 如您所见,realtime_links.html呈现了三个模板:
header
是一个简单的标头,显示数据库中的链接数。 link_list
显示链接列表及其关联的投票。 add_new_link
是添加新链接的一种形式。 清单4显示了header
模板。
header
模板
The Link Collection
We currently have {{collection_size}} links.
header
模板仅呈现h1
标签和集合大小的简短描述。 在JavaScript文件realtime_links.js中定义了collection_size
方法( 在下一部分中进一步讨论)。 流星会自动观察模板会插入哪些数据。 因此,当集合的大小更新时, header
模板也会自动更新。
请注意,此处使用的{{ ... }
语法类似于Ruby on Rails中的<%= ... %>
或PHP中的= ... ?>
。 它可以插入任意代码,因此您可以以这种方式插入任何有用的动态表达式。
清单5显示了link_list
模板。
link_list
模板
{{#each links }}
- {{> link_detail }}
{{/each }}
如您所见,清单5中的代码是链接列表。 来自realtime_links.js JavaScript文件的links
方法提供了此列表。 link_detail
模板为每个链接呈现。 请注意,您不必传递任何参数,因为Handlebars的#each
循环将每次迭代的当前上下文设置为当前对象。 换句话说, link_detail
模板的本地方法被正确地解释为每个链接对象的方法。
清单6显示了link_detail
模板,该模板控制每个单独链接显示的数据。
link_detail
模板
{{url}}
Stats: up: {{thumbs_up}} down: {{thumbs_down}}
net score: {{score}}
h1
元素仅显示当前链接的URL。 然后是一个简短的统计列表,其中包括链接被投票的次数,链接被拒绝的次数以及其净得分,这是两个值之间的差。 最后,有两个按钮:一个用于表示赞成或反对,或一个表示反对或反对。 JavaScript文件定义了这些按钮的行为,但是在深入了解这些按钮之前,还有一个模板需要检查。
清单7显示了add_new_link
模板。
add_new_link
模板
URL:
该模板只是一个文本输入字段和一个按钮,它们共同构成用于向列表中添加新URL的界面。
realtime_links.js
JavaScript代码可控制程序在客户端和服务器上的数据访问和事件回调。 if (Meteor.is_client)
语句标记了客户端部分,而if (Meteor.is_server)
语句标记了服务器部分。 流星提供了一种保护敏感代码的方法,以使恶意客户端无法看到源。 请参阅链接到流星文档相关主题的更多细节。
清单8显示了标头和链接列表帮助器函数。
Template.header.collection_size = function () {
return Links.find({}).count();
};
Template.link_list.links = function () {
return Links.find({}, {sort : {score: -1} });
};
header
模板使用清单中的第一个辅助函数,该函数仅返回links
集合的大小。 link_list
模板使用第二个帮助器函数,该函数返回从最高得分到最低得分排序的所有链接。
清单9有两个link_detail
模板的事件回调。
link_detail
事件回调 Template.link_detail.events =
{
'click input.thumbs_up' : function () {
Meteor.call('vote', this.url, 'thumbs_up');
},
'click input.thumbs_down' : function
() {Meteor.call('vote', this.url, 'thumbs_down');}
};
每个事件回调都处理一个表决上击或表决下击事件。 在这两种情况下,它们Meteor.call
在客户端使用Meteor.call
在服务器端进行函数调用。 如您所见,从客户端到服务器的调用很容易。 例如,序列化是自动处理的。
清单10显示了表单的事件回调,用户可以在其中添加新链接。
Template.add_new_link.events = {
'click input#add_url' :
dfunction () {
var new_url = $('#url').val();
var url_row = Links.findOne( {url:new_url} );
if(!url_row){
Links.insert( { url : new_url,
score: 0,
thumbs_up: 0,
thumbs_down: 0 });
}
Meteor.call('vote', url, 'thumbs_up');
}
};
首先,该表单尝试使用请求的URL定位现有的链接对象。 如果找到一个,它将请求视为对现有链接对象的投票。 如果找不到,它将创建一个新的链接对象,并对该新对象进行thumbs_up
投票。
这段代码说明了Meteor的功能和局限性,而Meteor尚未用于生产用途。 如您所见,客户端可以简单地在links
集合上调用insert
。 尽管这对开发人员很有用,但从安全角度来看,这是一个很大的问题。 幸运的是,开发人员正在积极地进行代码的auth
分支,该分支实现了强大的身份验证功能,同时仍保留了使Meteor更具吸引力的强大功能和灵活性。
此外,请认识到Meteor当前未实现所有MongoDB功能。 例如,Meteor不支持MongoDB upsert,后者会插入新数据或修改旧数据。 如果Meteor支持upserts,则可以编写清单11中所示的函数。
Template.add_new_link.events = {
'click input#add_url' : function () {
var new_url = $('#url').val();
Links.update( { url : new_url},
{ $set: {url : new_url},
$inc: { votes : 1 } } , true );
}
};
如您所见,使用upserts可以缩短代码。 这也可能会更快,因为它只需要往返服务器一次。 希望Meteor尽快实现对upsert和其他新功能的支持。
清单12中的代码在服务器上运行。 这是一个可以由客户端代码调用的方法。 这种方法vote
,允许客户端对特定URL进行thumbs_up
或thumbs_down
投票。 它使用Mongo的$inc
运算符来增加适当的投票计数器。 它还会根据需要增加或减少总分。 Meteor.startup
方法允许代码仅在服务器启动时运行。 然后, Meteor.methods
函数定义可以使用Meteor.call
在客户端上调用的Meteor.call
,如清单9所示。
vote
方法的代码 if (Meteor.is_server) {
Meteor.startup(function () {
Meteor.methods({
vote: function (url, field){
new_obj = { $inc: { } };
if(field =='thumbs_up'){
new_obj['$inc']['thumbs_up'] = 1;
new_obj['$inc']['score'] = 1;
}else{
new_obj['$inc']['thumbs_down'] = 1;
new_obj['$inc']['score'] = -1;
}
Links.update( { url : url}, new_obj );
}
});
});
}
与清单10一样,您可以在客户端上运行清单12中的代码。 但是,出于说明目的,它在服务器上运行。 随着Meteor安全模型的发展,敏感代码很可能会被开发为服务器端功能,如清单所示。
此时,您可以启动您的Meteor应用程序,如清单13所示,并在运行中看到它。
meteor
启动后,Meteor在端口3000上运行。打开Web浏览器,然后导航到http:// localhost:3000 /。
如果在“ 添加 URL”下输入URL ,然后单击“ 添加” ,则应该看到URL得分为one
。 然后,您可以单击Thumbs Up或Thumbs Down按钮来投票赞成或反对URL。 这是实时发生的,没有页面刷新。 如果打开新的Web浏览器,则可以在另一个窗口中执行相同操作,第一个窗口会立即反映所有更改。
当您添加多个URL时,您会看到得分最高的那个(得分被定义为正负投票)显示在顶部。 当您投票赞成或反对时,URL随排名变化而在列表中上下移动。 这是实时发生的,多个浏览器上的多个用户在输入投票时都收到相同的数据。
Meteor是一个包含许多有趣概念的尖端Web框架。 它对实时数据的支持既有吸引力又重要,特别是考虑到与其他技术一起使用时,实时支持是最好的事。 随着实时交互对于Web的未来变得越来越重要,Meteor轻松,快速地实时处理复杂数据集的能力也将变得越来越重要。
翻译自: https://www.ibm.com/developerworks/opensource/library/wa-meteor/index.html
基于meteor开发的