RubyOnRails with Ajax

原文出处:跨越边界: Ajax on Rails

整理测试:cheungmine

Ajax 即 Asynchronous JavaScript XML,重新定义了基本的浏览器使用模型。原模型一次呈现一个页面。Ajax 允许浏览器在页面更新的间隔同服务器进行交流。这样做的好处是带来更加丰富的客户体验。Ajax 是这样运行的:使用 JavaScript 客户端库在客户机和服务器间发送 XML。Ajax 开发人员可以在任何时刻从客户机发送异步请求,因而在服务器处理这些请求时,用户交互可以继续进行。

1 Ajax 请求的流程:

1) 一个事件(如用户的鼠标点击或编程计时器的触发)启动一个 JavaScript 函数。
2)JavaScript 函数为部分页面而不是整个页面创建一个请求。JavaScript 随后通过 HTTP 将该请求发送到 Web 服务器。
3)此 HTTP 请求调用服务器上的一个脚本,如 Rails 控制器方法或 Java servlet。
4)该服务器脚本创建一个 XML 文档并将其返回给服务器。
5)在接收结果的同时,客户机异步处理创建、更新或删除部分 Web 页面,如列表元素、div 标记或图像。

Ajax 解决方案的组件是:

1)客户端 JavaScript 库,用来管理异步请求。
2)服务器端 JavaScript 库,用来处理进来的请求,并构造一个 XML 响应。
3)客户端 JavaScript 库,用来处理生成的 XML。
4)文档对象模型(DOM)的库,允许对现有 Web 页面进行更新。
5)辅助例程,用来处理不可避免的 UI 和集成问题。

下面以一个实际的例子来说明Ajax的用法和必要性:

2 没有 Ajax 的简单的 Rails 应用程序

启动Instant Rails。如果你不了解如何使用Rails,请快速浏览我的上一篇文章:使用 RubyOnRails 快速搭建LBS网站。
启动Ruby Console Window,输入下面的命令:

清单1:

rails ajax
cd ajax
ruby script/generate controller Say show time
ruby script/server

第一行和第二行代码生成一个 Rails 项目,并切换到新目录。第三行代码生成一个叫做 Say 的控制器,并增加两个动作:show 和 time。下面显示该控制器的代码:

清单2:

#say_controller.rb
class SayController < ApplicationControllerdef showenddef timerender:text=>"The current time is #{Time.now}"end
end

找到...\rails_apps\ajax\app\views\say\show.html.erb,修改如下:

清单3:

<h1>Ajax show</h1>
Click this link to show the current <%= link_to "time", :action => "time" %>.

Ruby 用其表达式的值替代 <%=h 和 %> 之间的代码。在这个示例中,link_to 方法是一个生成简单 HTML 链接的辅助例程。可以通过执行该代码看到该链接。通过键入:ruby script/server 启动网站ajax服务器,然后将浏览器指向 http://localhost:3000/say/show 。结果显示如下:

Ajax show

Click this link to show the current time.

在浏览器中,单击菜单项来查看页面源代码:

清单4:

<h1>Ajax show</h1>
Click this link to show the current <a href="/say/time">time</a>.

点击time链接跳转到time页面,如下图:

很快就能看到这个 UI 的一个问题。这两个视图show和time不从属于单独的页面。为反复更新时间,每次都需要单击该链接和 Back 按钮。将该链接和时间放到相同的页面中也许可以解决这个问题。但如果该页面变得非常大或非常复杂,重新显示整个页面会很浪费,也会很复杂。下面的采用Ajax方案来重新解决这个问题。

3 Ajax方案

Ajax 让您可以只更新 Web 页面的一个片段。Rails 库为您处理大部分的工作。要将 Ajax 添加到这个应用程序中,需要以下四个步骤:

1)配置 Rails 以使用 JavaScript。
2)更改时间链接来提交 JavaScript Ajax 请求,而不是仅呈现一个 HTML 链接。
3)定要更新的 HTML 片断。
4)为更新的 HTML 内容准备一个位置。
5)构建一个控制器方法,或者一个视图来呈现 Ajax 响应。

将...\rails_apps\ajax\app\views\say\show.html.erb,修改如下:

清单5:

<%= javascript_include_tag :defaults %>
<h1>Ajax show</h1>
Click this link to show the current
<%= link_to_remote "time", :update => 'time_div', :url => {:action => "time"} %>.<br/>
<div id='time_div'>
</div>

首先,为处理配置,简单地将必要的 JavaScript 库直接包含在视图中。通常,还会有更多的视图,为避免重复,可以将 JavaScript 文件包含在一个公共的 Rails 组件中,如 Rails 布局。本例只有一个视图,所以一切从简。
其次,改变了链接标记来使用 link_to_remote。您一会儿就能看到这个链接的作用。请注意下列三个参数:

1)链接文本:从非 Ajax 的例子中照搬过来。
2):update 参数。如果您以前没见过这种语法,那么就把 :update => 'time_div' 当作是一个已命名的参数,其中的 :update 是名称,update_div 是值。此代码告诉 Prototype 库:此链接中的结果将用 time_div 这一名称更新 HTML 组件。
3)代码 :url => {:action => "time"} 指定该链接将调用的 URL。:url 从一个哈希映射表中获取值。在实际中,该哈希映射表只有一个针对控制器动作的元素::time。理论上,该 URL 也可以包含控制器的名称和控制器需要的任何可选参数。

还可以看到空的 div,Rails 将用当前时间更新它。在浏览器中,装载页面 http://localhost:3000/say/show。单击该time链接,注意到当前页面的地址并未更改:

查看页面源码:

清单6:

<script src="/javascripts/prototype.js?1311034732" type="text/javascript"></script>
<script src="/javascripts/effects.js?1311034732" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1311034732" type="text/javascript"></script>
<script src="/javascripts/controls.js?1311034732" type="text/javascript"></script>
<script src="/javascripts/application.js?1311034732" type="text/javascript"></script>
<h1>Ajax show</h1>
Click this link to show the current
<a href="#" onclick="new Ajax.Updater('time_div', '/say/time', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('7896f1ca7446192535dc697c4abcf86db48be19c')}); return false;">time</a>.<br/>
<div id='time_div'>
</div>

请注意包含的 JavaScript 列表。Rails 辅助方法(include_javascript_tags :defaults)为您构建了此列表。接下来,看到一个用来构建新的 Ajax.Updater 对象的 JavaScript 函数调用,而不是一个 HTML 链接。名为 asynchronous 的参数被设置为 true。最后,在 HTML div 标记中看不到值,这是由于初始页面在那里没有值。

4 使用其他 Ajax 选项

Ajax 能生成强大的动作,甚至能生成一些预料不到的动作。例如,用户也许没注意到更新的时间链接。link_to_remote 选项让您能够轻易地将特殊效果应用到该条目上,从而让用户注意到该结果。现在将应用一些效果。请更改 show.html.erb 中的 link_to_remote 辅助方法,更改后的文件如下:

清单7:

<%= javascript_include_tag :defaults %>
<h1>Ajax show</h1>
Click this link to show the current
<%= link_to_remote "time", :update => 'time_div', :url => {:action => "time"},:complete => "new Effect.Highlight('time_div')" %>.<br/>
<div id='time_div'>
</div>

在浏览器中,装载页面 http://localhost:3000/say/show。单击该time链接,可以看到特殊的颜色效果。

到目前为止,链接是您见到的惟一触发器。Ajax 还有许多其他的可用武器,一些由用户驱动,而另一些由程序事件驱动,如时钟。它是一个像闹钟一样并不需要用户干预的东西。可以用 Ajax 的 periodically_call_remote 方法定期更新时钟。请更改 show.html.erb 代码如下:

清单8:

<%= javascript_include_tag :defaults %>
<h1>Ajax show</h1>
<%= periodically_call_remote :update => 'time_div', :url => {:action => "time"},:frequency => 1.0 %>
<div id='time_div'>
</div>

在浏览器中,装载页面 http://localhost:3000/say/show。可以看到时间自动更新了。尽管 Rails 视图中的代码和不含 Ajax 的版本相似,但背后的代码却很不同:此版本使用 JavaScript 代替了 HTML。可以通过在浏览器中查看源代码:

清单9:

<script src="/javascripts/prototype.js?1311034732" type="text/javascript"></script>
<script src="/javascripts/effects.js?1311034732" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1311034732" type="text/javascript"></script>
<script src="/javascripts/controls.js?1311034732" type="text/javascript"></script>
<script src="/javascripts/application.js?1311034732" type="text/javascript"></script>
<h1>Ajax show</h1>
<script type="text/javascript">
//<![CDATA[
new PeriodicalExecuter(function() {new Ajax.Updater('time_div', '/say/time', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('7896f1ca7446192535dc697c4abcf86db48be19c')})}, 1.0)
//]]>
</script>
<div id='time_div'>
</div>

请一定注意这里发生的情况。您正在一个更高层的抽象之上有效地工作,而不是使用小块的自定义 JavaScript 片段,Ruby on Rails 模板系统使使用模型变得相当自然。

正如之前提到的那样,我正从控制器中直接呈现文本。这一简化使开始编程变得很容易,但却不能一直持续下去。视图应该处理显示,控制器应该在视图和模型间调度数据。这项设计技术叫做模型-视图-控制器(MVC),它使对视图或模型的更改更容易分隔开。为使这个应用程序符合 MVC,可以让 Rails 呈现默认视图,正如预料的那样,该内容将替代 time_div 之前的内容。请按照清单 10 更改 say_controller.rb 中的 time 方法(对比清单2):

清单 10:

def time@time = Time.now
end

请按照清单 11 更改 ...\rails_apps\ajax\app\views\say\time.html.erb的代码:

清单 11:

<p>The current time is <%=h @time %></p>

控制器方法设置一个名为 @time 的实例变量。由于控制器什么都没明确地呈现出来,Rails 将 time.html.erb 视图呈现出来。 这种使用模型和呈现一个不含 Ajax 的视图完全一致。 可以再一次看到, Rails 使开发人员不必考虑使用 Ajax 和不使用 Ajax 的应用程序间的区别。从传统的 Web 应用程序到 Ajax,该使用模型都惊人地相似。由于使用 Ajax 的成本如此之低,越来越多的 Rails 应用程序都开始利用 Ajax。

5 Rails 中 Ajax 的其他用法

Rails Ajax 体验领域宽广且内容深刻。下面是 Rails 中 Ajax 的一些通常用法:

1)提交远程表单。 除了必须异步提交以外,Rails 中的 Ajax 表单和传统表单的执行方式完全一样。这意味着 Rails 中的 Forms 辅助标记让您必须指定一个要更新的 URL,执行可视化的效果,正如使用 link_to_remote 一样。正如 link-to-remote 扩展了 link_to 辅助方法一样,Rails submit_to_remote 扩展了一个 Rails submit 辅助方法。
2)执行复杂脚本。 Rails 开发人员常常需要执行复杂的脚本,远不止更新单个 div 和执行效果那么简单。为此,Rails 提供 JavaScript 模板。用 JavaScript 模板,可以将任意 JavaScript 脚本作为 Ajax 请求的结果来执行。这些模板的一些常见用法(叫作 RJS 模板)为更新多个 div、处理表单验证和管理 Ajax 错误场景。
3)拼写补全。 您一定想基于数据库中的条目为您的用户提供拼写补全服务。例如,如果用户键入 Bru,我想让我的应用程序注意到数据库中 “Bruce Tate” 这个值。可以使用 Ajax 定期检查字段的更改,并根据用户键入的内容发送拼写补全建议。
4)动态构建复杂表单。 在业务领域里,常常需要查看部分已完成表单,然后才能知道用户应该完成哪个字段。例如,如果用户拥有一些特定种类的收入或费用,那么 1040EZ 纳税单是无效的。可以在这个过程中用 Ajax 更新表单。
5)拖放。 可以用 Rails 快速实现拖放支持,这比大多数其他框架要省力得多。

6 转载评语

如此精彩的文章,不但用最简单的示例清晰地说明了Ajax在Rails中是如何被使用的,原理和背后发生的逻辑。同时也让我们明白了Rails的MVC框架带来的简洁和便利。虽然是转载,但原文中的全部代码都经过我亲自测试,去掉了一些旧版本的语法错误。请支持原作者,点击:

http://www.ibm.com/developerworks/cn/java/j-cb12056/index.html#resources

RubyOnRails with Ajax相关推荐

  1. 一个使用Ruby on Rails开发LBS网站的简单实例

    一个使用Ruby on Rails开发LBS网站的简单实例 cheungmine 2011-7 这几天一直在学习使用Ruby on Rails(RoR),想建立一个功能全面一点的LBS(Locatio ...

  2. 《Ajax基础教程》一书推荐的JS工具备忘

    Firefox的Web开发扩展 http://chrispederick.com/work/firefox/webdeveloper/ MemTronic的HTML/JavaScript Crunch ...

  3. golang ajax jquery,golang - 从http请求返回json字符串的库/包

    没有什么它使用现有的系统封装,它相当简单的go package main import ( "encoding/json" "fmt" "net/ht ...

  4. (转)基于Ajax的应用程序架构汇总

    浏览器端框架被划分成两大类: ·应用程序框架:提供浏览器的功能,但是常以包括窗口小部件抽象和另外的部件而出名,其功能主要围绕桌面GUI框架. ·基本结构框架:提供基本的管道和可移植的浏览器抽象,让开发 ...

  5. Ajax 技术汇总(转载)

    AJAX AJAX全称为"Asynchronous JavaScript and XML"(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术. Ajax ...

  6. 迅速成为炙手可热的新一代程序员看《Ajax基础教程》

      Ajax基础教程 Foundations of Ajax   | Ryan Asleson著 金灵译 人民邮电出版社  | 7-115-14481-8/TP·5211 | 2006-02-16 | ...

  7. html+spring boot简单的ajax数据传输实现

    本篇讲解在前后端不分离情况下的html+spring boot的项目数据传输实现 首先,后台我写了三个接口 package com.demo.ajax.controller;import com.de ...

  8. form表单提交前进行ajax或js验证,校验不通过不提交

    在使用form表单进行提交数据前,需要进行数据的校验->表单的校验(如:两次密码输入是否相同)+后台数据的校验(如:账号是否存在),这个时候,如果哪步校验不通过,表单将停止提交,同时避免后台主键 ...

  9. 使用ajax不刷新页面获取、操作数据

    在使用jsp或html时,利用ajax达到不刷新页面就可以获取.操作数据. 首先上代码 (html+js) 在此处需要引入jquery插件 <!-- 这是页面部分 html--> < ...

  10. Ajax接收Java异常_java – 处理来自Servlet的Jquery AJAX响应中的异常

    我的servlet代码是 try{ //something response.setStatus(201); out.print("Data successfully saved" ...

最新文章

  1. Huggingface及BERT代码介绍
  2. iOS开发网络篇—多线程断点下载
  3. [云炬创业基础笔记]第七张创业团队测试3
  4. 推荐一款日志切割神器,好用到爆!!
  5. linux 从命令行自动识别文件并将其打开的命令
  6. php好玩的源码_PHP 经典有趣的算法
  7. Visual Studio Code 10 月 Python 扩展更新
  8. 再学 GDI+[63]: 路径画刷(3) - SetFocusScales、GetFocusScales
  9. ubuntu 重装系统备份数据 ubuntu安装kde桌面
  10. eclipse-indigo 中 user libraries 自动部署 WEB-INF/lib 配置
  11. freebsd 运行linux,Freebsd 下运行 QQ For Linux 的方法
  12. 云计算,SDN,虚拟化三者关系
  13. Python 入门演示 1
  14. 打算开源一个低代码平台,第二天,包含【工作流,业务流,财务,APQC】。技术站 React,typescript,java,mysql
  15. 实验二:递归下降语法分析
  16. r7 3700u性能怎么样 相当于英特尔什么水平
  17. 怎么把微信公众号的文章里的音频或视频下载到电脑和手机
  18. 用LSTM做文本情感分类(以英文为例)附github代码
  19. C语言入门:猴子吃桃问题
  20. Spring整合Kafka

热门文章

  1. java 手机类测试
  2. idea远程调试debug
  3. Java:项目整体结构分析
  4. python自动化办公手册之python操作PPT
  5. plecs中以RLC为例介绍c-scripe建立微分方程的过程
  6. 路径规划——RRT算法实现
  7. sas入门之(三)条件语句,循环语句,input语句
  8. Fragstats4.2.1入门心得
  9. 百度文库和豆丁网的在线文档阅读功能
  10. 网络安全工程师毕业答辩杂记