xiaoxiaoxuewen 2014-09-25
使用 Meteor 轻松开发实时网站
快速实现几乎实时地响应用户交互的数据驱动应用程序
由于 Web 无处不在,即便是很小的数据交付延迟都有可能刺激到用户。他们希望数据即时更新。不幸的是,Web 技术无法实现这种实时访问。尽管数据访问正快速标准化为一些对象关系映射 (Object-Relational Mapping, ORM) 模型,但实时通信没有任何类似的解决方案。本文将讨论 Meteor,这是一个旨在解决此问题的激动人心的新 JavaScript 框架。
Meteor 是一种新的 JavaScript 框架,用于自动化和简化实时运行的 Web 应用程序的开发。它使用一个名为分布式数据协议 (Distributed Data Protocol, DDP) 的协议来处理实时通信,使用 WebSockets 的新浏览器以及使用 Asynchronous JavaScript + XML (Ajax) 长轮询的旧浏览器来支持这种协议。在这两种情况下,浏览器到服务器的通信是透明的。
DDP 协议旨在处理 JavaScript Serialized Object Notation (JSON) 文档集合,使 JSON 文档容易创建、更新、删除、查询和访问。因为 DDP 是一种开源协议,所以您可将它连接到任何客户端或数据存储。它为 MongoDB 提供了开箱即使用支持。
事实上,Meteor 提供了两个 MongoDB 数据库:一个客户端缓存数据库和服务器上的一个 MongoDB 数据库。当一个用户更改一些数据时(例如通过单击 Save),在浏览器中运行的 JavaScript 代码会更新本地 MongoDB 中的相应的数据库项,然后向服务器发出一个 DDP 请求。该代码立即像操作已获得成功那样继续运行,因为它不需要等待服务器回复。与此同时,服务器在后台更新。如果服务器操作失败或返回一个意外结果,那么客户端 JavaScript 代码会依据从服务器新返回的数据立即进行调整。这种调整称为延迟补偿,向用户提供了更高的认知速度。
显然,甚至连 Meteor 的模板系统也是为简化实时通信而设计的。在大多数 Web 框架中,您可以轻松地混合使用超文本标记语言 (HTML) 和代码,或者与 HTML 等效的标记,比如 HTML 抽象标记语言 (Haml)。这使您能够轻松地将来自数据库的动态值插入发送给用户的页面中。在这之后,您应该负责准备提供一个系统来观察对数据的更改,然后更新您的标记。但是,Meteor 中的模板系统用于记录访问了模板中的哪些数据,并自动回调,以便在底层数据更改时调用此 HTML,使实时模板变得更加简单快捷。
本文示例源码下载:
------------------------------------------分割线------------------------------------------
具体下载目录在 /2014年资料/9月/26日/使用 Meteor 轻松开发实时网站
------------------------------------------分割线------------------------------------------
Meteor 的模板功能可使众多实时应用程序更容易编写。例如,假设您希望创建一个的站点,用户可在其中输入链接(即统一资源定位符,URL),并投票肯定和否决它们,而且赢得流行度竞赛的 URL 会显示在一个列表顶部。通过使用 Meteor,您可以轻松地实时编写这样一个应用程序,以便用户可在其他用户投票时看见他们的 65 张选票。
要安装 Meteor,可以将 清单 1 中所示的代码键入到一个 Linux® 或 Mac OS® X 终端中。Meteor 不支持 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
Meteor 创建了一个目录,其中包含一个 HTML 文件、一个 JavaScript 文件和一个级联样式表 (CSS) 文件。最后一个文件是一个标准 CSS 文件,但前两个值得讨论一下。您可以从 下载 一节下载 realtime_links.html 和 realtime_links.js 文件的完整版本。
清单 3 显示了 realtime_links.html 文件的标头和正文片段。
<head> <title>Realtime Links Demo</title> </head> <body> {{> header }} {{> link_list }} {{> add_new_link }} </body>
可以看到,HTML 模板的开头非常简单。无需担忧如何包含 BODY
标记、DOCTYPE
修饰符甚至 JavaScript 和 CSS 文件。Meteor 会为您处理所有这些操作。有关 Meteor 的 JavaScript 和 CSS 包的更多信息,请参阅 参考资料,获取 Meteor 网站的链接。
{{>
语法表示 “呈现此模板”。可以看到,realtime_links.html 呈现了 3 个模板:
header
是一个简单头部,显示了数据库中的链接数量。link_list
显示了链接的列表和它们的相关投票。add_new_link
是添加新链接的表单。清单 4 显示了 header
模板。
header
模板<template name="header"> <h1>The Link Collection</h1> <p>We currently have {{collection_size}} links.</p> </template>
header
模板呈现了一个 h1
标记以及对集合大小的简短描述。collection_size
方法是在 JavaScript 文件 realtime_links.js 中定义的(这将在 下一节 中详细讨论)。Meteor 自动观察某个模板插入了哪些数据片段。所以,在更新集合大小时,header
模板会自动更新。
请注意,这里使用的 {{ ... }
语法类似于 Ruby on Rails 中的 <%= ... %>
或 PHP 中的 <?= ... ?>
。它可插入任意代码,所以能够以这种方式插入任何有用的动态表达式。
清单 5 显示了 link_list
模板。
link_list
模板<template name= "link_list"> <ul> {{#each links }} <li> {{> link_detail }} </li> {{/each }} </ul> </template>
如您所见,清单 5 中的代码是一个链接列表。realtime_links.js JavaScript 文件中的 links
方法提供了此列表。系统会向每个链接呈现link_detail
模板。请注意,无需传递任何参数,因为 Handlebars 的 #each
循环会将每次迭代的当前上下文设置为当前对象。换句话说,会将 link_detail
模板的本地方法正确解释为每个链接对象的方法。
清单 6 显示了 link_detail
模板,它控制了为每个链接显示的数据。
link_detail
模板<template name="link_detail"> <div id="link-{{id}}"> <h1>{{url}}</h1> <p><strong>Stats:</strong> up: {{thumbs_up}} down: {{thumbs_down}} net score: {{score}}</p> <input type="button" value="Thumbs Up" class="thumbs_up" url="{{url}}" /> <input type="button" value="Thumbs Down" class="thumbs_down" url="{{url}}" /> </div> </template>
h1
元素简单地显示当前链接的 URL。然后会提供一个间断的统计清单,其中包含一个链接被支持的次数、被否决的次数和它的净分数(也就是两个值的差)。最后,有两个按钮:一个用于投赞成或支持票,另一个用于投反对或否决票。JavaScript 文件定义这些按钮的行为,但是在深入介绍此主题前,还有一个模板需要了解。
清单 7 显示了 add_new_link
模板。
add_new_link
模板<template name="add_new_link"> <div id="new_link_form"> URL: <input id="url"> <input type="button" value="Click" id="add_url" /> </div> </template>
该模板只是一个文本输入字段和一个按钮,它们共同形成了向您列表中添加新 URL 的界面。