Ruby on Rails框架和Ajax的完美配合(二)

日期: 2007-12-04 作者:Bruce Tate 来源:TechTarget中国

  首先,更改 app/views/ajax/show.rhtml 中的代码,使其与清单 5 类似:

  清单 5. 更改显示视图来使用 Ajax

<%= 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。您一会儿就能看到这个链接的作用。请注意下列三个参数:

  链接文本:从非 Ajax 的例子中照搬过来。

  :update 参数。如果您以前没见过这种语法,那么就把 :update => ‘time_div’ 当作是一个已命名的参数,其中的 :update 是名称,update_div 是值。此代码告诉 Prototype 库:此链接中的结果将用 time_div 这一名称更新 HTML 组件。

  代码 :url => {:action => "time"} 指定该链接将调用的 URL。:url 从一个哈希映射表中获取值。在实际中,该哈希映射表只有一个针对控制器动作的元素::time。理论上,该 URL 也可以包含控制器的名称和控制器需要的任何可选参数。

  在清单 5 中,还可以看到空的 div,Rails 将用当前时间更新它。

  在浏览器中,装载页面 http://localhost:3000/ajax/show。单击该链接,将看到图 3 中的结果。

  图 3. 含 Ajax 的视图

  为了很好地了解这里发生的情况,请查看该 Web 页面的源代码。清单 6 显示了该代码:

  清单 6. 显示模板的结果(在启用 Ajax 的情况下)

<script src="/javascripts/prototype.js?1159113688" type="text/javascript"></script>
<script src="/javascripts/effects.js?1159113688" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1159113688" type="text/javascript"></script>
<script src="/javascripts/controls.js?1159113688" type="text/javascript"></script>
<script src="/javascripts/application.js?1159113688" type="text/javascript"></script>
<h1>Ajax show</h1>
Click this link to show the current
<a href="#" onclick="new Ajax.Updater(
   ‘time_div’, ‘/ajax/time’, {asynchronous:true, evalScripts:true});
   return false;">time</a>.<br/>
<div id=’time_div’>

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

  使用其他 Ajax 选项

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

  清单 7. 添加效果

<%= link_to_remote "time",
    :update => ‘time_div’,
    :url => {:action => "time"},
    :complete => "new Effect.Highlight(‘time_div’)" %>

  最佳 Ajax 效果会使您的更改获得临时的关注,但却不会永久持续。您的目标应该是把更改提示给用户,而不打断他们的工作流。像这种用黄色来弱化强调的技术,或用滑入内容或淡出内容来让用户注意的技术都不是长久之计。

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

  清单 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>

  图 4 显示了结果:不需要用户干预,每隔一秒钟进行更新的时钟:

  图 4. 用 Ajax 定期更新的时钟

  尽管 Rails 视图中的代码和不含 Ajax 的版本相似,但背后的代码却很不同:此版本使用 JavaScript 代替了 HTML。可以通过在浏览器中查看源代码看到清单 9 中的代码:

  清单 9. periodically_call_remote 的源代码

<script src="/javascripts/prototype.js?1159113688" type="text/javascript"></script>
<script src="/javascripts/effects.js?1159113688" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1159113688" type="text/javascript"></script>
<script src="/javascripts/controls.js?1159113688" type="text/javascript"></script>
<script src="/javascripts/application.js?1159113688" type="text/javascript"></script>
<h1>Ajax show</h1>
<script type="text/javascript">
//<![CDATA[
new PeriodicalExecuter(function() {new Ajax.Updater(
   ‘time_div’, ‘/ajax/time’, {asynchronous:true, evalScripts:true})}, 1.0)
//]]>
</script>
<div id=’time_div’>
</div>

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

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

  清单 10. 重构

def time
  @time = Time.now
end

  请按照清单 11 更改 app/views/ajax/time.rhtml 中的视图:

  清单 11. 使用视图呈现 Ajax 内容

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

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

  Rails 中 Ajax 的其他用法

  Rails Ajax 体验领域宽广且内容深刻 —— 我无法用单篇文章甚至一系列文章来概括其深刻的内容。我只能指出 Rails Ajax 支持可以解决其他一些问题。下面是 Rails 中 Ajax 的一些通常用法:

  提交远程表单。 除了必须异步提交以外,Rails 中的 Ajax 表单和传统表单的执行方式完全一样。这意味着 Rails 中的 Forms 辅助标记让您必须指定一个要更新的 URL,执行可视化的效果,正如使用 link_to_remote 一样。正如 link-to-remote 扩展了 link_to 辅助方法一样,Rails submit_to_remote 扩展了一个 Rails submit 辅助方法。

  执行复杂脚本。 Rails 开发人员常常需要执行复杂的脚本,远不止更新单个 div 和执行效果那么简单。为此,Rails 提供 JavaScript 模板。用 JavaScript 模板,可以将任意 JavaScript 脚本作为 Ajax 请求的结果来执行。这些模板的一些常见用法(叫作 RJS 模板)为更新多个 div、处理表单验证和管理 Ajax 错误场景。

  拼写补全。 您一定想基于数据库中的条目为您的用户提供拼写补全服务。例如,如果用户键入 Bru,我想让我的应用程序注意到数据库中 “Bruce Tate” 这个值。可以使用 Ajax 定期检查字段的更改,并根据用户键入的内容发送拼写补全建议。

  动态构建复杂表单。 在业务领域里,常常需要查看部分已完成表单,然后才能知道用户应该完成哪个字段。例如,如果用户拥有一些特定种类的收入或费用,那么 1040EZ 纳税单是无效的。可以在这个过程中用 Ajax 更新表单。

  拖放。 可以用 Rails 快速实现拖放支持,这比大多数其他框架要省力得多。

  结束语

  Ajax 并不是没有问题。当 Ajax 运行良好时,整个体验会是激动人心的。但当运行不顺利时,您也许会发现对其进行调试是一个全新的领域,调试技术和工具还没有其他语言中那么成熟。Ruby on Rails 的确有一个核心优势:简单。Rails 包装器(加上很棒的社区支持)使得进入这一新环境变得简单,而且最初的投资非常低。但 Rails 支持也仅限于此。这两个框架还没有覆盖 Ajax 的全部内容,无法满足每个用户的需求。

  Java 语言有更多的 Ajax 框架和方法可供选择。可以找到更具灵活性的,也可以找到具有很棒的支持基础的。但灵活性是要付出代价的。您不仅需要一个强大的 Ajax 框架,也需要一个 Web 开发框架。例如,集成 JSF 框架和集成 Struts 是两种截然不同的体验。新技术通常追求简单。对于那些在 UI 中需要 Ajax 的出色特性,却又不需要由 Java 提供的高级企业集成特性的问题,Ajax on Rails 也许正合适。下一次,我将更深入地介绍 JavaScript。请继续关注跨越边界。

 

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐