在 Ruby on Rails 中使用 Ajax
贡献者:Brian Leonard,维护者:Gail Chappell
2007 年 12 月 [修订号:V6.0-4]
翻译:Dave(NetBeans 中文社区成员)
在本教程中,我们将介绍在 NetBeans Ruby on Rails 项目中添加 Ajax 支持。教程示例展示了如何在 web 日志中动态地添加评论。
|
目录
|
|
 |
教程需求
学习本教程需要以下技术和资源:
创建样例数据库
注意:本教程使用 MySQL 数据库服务器。您可以参考
安装和配置 Ruby 支持一文以获取有关如何在 Ruby 应用程序中使用 MySQL 数据库服务器的信息。该文档同样介绍了如何使用 JavaDB 数据库服务器作为替代。
- 打开一个命令行窗口。
- 如果 MySQL 数据库服务器尚未被启动,请先将其启动。
- 键入如下命令来创建开发数据库,并按“Enter”键。
mysqladmin -u root -p create rubyweblog_development
注意:如果 root 用户不要求密码,请省略 -p 参数。
-
在 IDE 中打开 rubyweblog 项目。
注意:如果是初次打开或者创建 Ruby 项目,IDE 会检查您是否有除了绑定的 JRuby 软件之外其他的 Ruby 安装。如果有,IDE 会显示一个对话框,询问您选择使用哪个软件。若您想要使用绑定的 JRuby 解释器,选择 JRuby;或者您喜欢使用您自己的 Ruby 安装,那就选择您自己的安装。更多信息,请参考《安装和配置 Ruby》教程中的配置 IDE 使用您自己的 Ruby 安装一节。
-
如果您的数据库要求密码,请编缉 database.yml 文件,并在开发配置部分中提供密码。保存该文件。
要快速访问 database.yml 文件,按 Alt+Shift+O(在 Mac 系统中按 Ctrl+Shift+O),在“文件名”文本框中键入 database.yml,然后按“Enter”键。
-
右键点击 rubyweblog 节点,选择“迁移数据库”>“到当前版本”。
该操作会更新数据库以加入 posts 表和 comments 表。 迁移完成时会在“输出”窗口显示。
- 运行应用程序并发表一篇新文章。
-
点击“Permalink”,然后给该文章添加一条评论。
可以发现当添加评论时,整个页面都被重新加载了。
创建局部模板
在当前的 rubyweblog 项目中,无论何时读者向页面添加评论,页面上的 blog 条目和所有评论都会被重新载入。更好的解决方案是使用 Ruby on Rails 框架中的 Ajax 支持来动态加载这些评论。作为使用 Ajax 的预先准备,需要创建局部模板来存储用于显示评论的代码。使用局部模板的好处是可以多次调用局部模板(显示 blog 中每个评论需要一次), 而无需渲染 blog 条目本身。
-
右键点击 rubyweblog 节点,选择“新建”>“RHTML File”。将文件命名为 _comments,并将其放置在 app\views\blog 文件夹中。
IDE 会创建 _comments 文件,并将其在编辑区打开。 注意,局部模板的文件名使用下划线(_)开头,以区别于完全模板。
当前,显示评论的代码在文件 show.rhtml 中。而在下一步,则会从 show.rhtml 中删除这部分代码,并将代码粘贴至局部模板 _comments.rhtml 中。
-
转至 rubyweblog >“Views”> blog 文件夹 ,并打开 show.rhtml。剪切用于显示评论的代码(如代码示例 1 中所示)。将代码粘贴至 _comments.rhtml 文件,替换其中所有已有内容。
代码示例 1:从 show.rhtml 中剪切,并粘贴至 _comments.rhtml 中的代码 |
<ul> <% @post_comments.each do |comment| %> <li><%= h comment.comment %><br> <div style="color: #999; font-size: 8pt"> Posted on <%= comment.created_at.strftime("%B %d, %Y at %I:%M %p") %>
</div> </li> <% end %> </ul>
|
-
返回 show.rhtml 文件,插入下面的 HTML <div> 标签。将其添加在 <h4>Comments</h4>之后,之前被删除的代码的位置。
代码示例 2:用于 show.rhtml 的 <div> 标签 |
<div id="comments"> <%= render(:partial => 'comments', :object => @post_comments) %> </div>
|
此段代码会创建一个名为 comments 的 <div> 元素。@post_comments 变量包含了局部模板 _comments 显示的评论。
-
选择“文件”>“全部保存”,然后运行应用程序。
-
点击“Permalink”,然后给文章添加一条评论。
此时,应用程序的表现和前面如出一辙。但它现在已被设计成可以开始使用 Ajax 支持了。
添加 Ajax 支持
在项目中添加 Ajax 支持的第一步是加入 JavaScript 库,Prototype 和 script.aculo.us。这些库是与 Ruby on Rails 绑定在一起的。Prototype 库提供了 Ruby on Rails 中 Ajax 实现的基础,而script.aculo.us 库则提供了视觉特效,可在应用程序中随意添加。
- 展开“Views”>“layouts”,然后打开
blog.rhtml 文件。
-
在包含 stylesheet_link_tag 的行下面,添加如下代码行:
<%= javascript_include_tag :defaults %>
此行代码会加入与 Ruby on Rails 绑定的 JavaScript 库:Prototype 和 script.aculo.us。下一步是创建 form_remote_tag,以触发 Ajax 动作。
- 打开
show.rhtml 文件。删除已有的 form_tag(执行 HTTP POST),并将其替换成下面的 form_remote_tag(执行 XMLHTTPRequest)。
<% form_remote_tag :url => {:action => "post_comment"} do %>
此行代码会触发用于 blog_controller.rb 文件中 post_comment 操作的 Ajax 动作。而此时,整个页面仍然会在读者提交评论时重新加载。这是因为post_comment 动作会通过调用 show 动作强制重新加载。最后一步即是编缉 blog_controller.rb 文件,删除该调用。
- 展开“Controllers”节点,打开
blog_controller.rb 文件。
- 滚动至
post_comment 动作,注释掉 redirect_to 调用。
# redirect_to :action => 'show', :id => flash[:post_id]
如果您现在就运行应用程序,并添加一条评论,则该评论不会被显示出来。您必须在下一步插入 Ruby JavaScript (RJS)模板来处理 XMLHTTPRequest。
添加 RJS 实现动态更新
最后的步骤是使用内建的 RJS 支持来动态更新 blog 上的评论。
-
在“Views”节点中,右键点击“blog”节点,选择“新建”->“Empty RJS Template”。
- 设置“文件名”为
post_comment,并将其仿真在 app\views\blog 文件夹中。
-
删除已有的页面对象,然后在该位置插入下面的页面对象。
page.replace_html 'comments', :partial => 'comments', :object => @post_comments
page[:comment_comment].clear
回忆一下,show.rhtml 文件包含一个名为 comments 的 HTML div 标签(参见代码示例 2)。在此段代码的第一行中,replace_html 使用 DHTML 动态地将 show.rhtml 文件中该 div 标签内的这一部分 HTML 代码替换为局部模板 _comments.rhtml 中的 HTML 代码。而@post_comment 变量则含有局部模板 _comments 显示的评论。此段代码的第二行会在用户提交评论后清空文本框。
不过您现在运行该应用程序,评论依然不会显示,因为变量 @post_comment 是空的。如果您回头看看 blog_controller.rb 文件,您会发现 @post_comment 是在 show 动作中设置的,而它不再被调用了。因此现在必须编缉 blog_controller.rb 文件。
-
打开 blog_controller.rb 文件,找到 post_comment 动作,在早先注释掉的重定向语句后面添加如下三行代码:
代码示例 3:用于 blog_controller.rb 文件的更新 |
#redirect_to :action => 'show', :id => flash[:post_id] @post = Post.find(flash[:post_id]) @post_comments = @post.comments.collect flash[:post_id] = @post.id #Store the post.id back in the flash
|
此段代码的第一行会调用 flash(类似 HTTP 会话,但可以跨越单个请求)。当在 flash 中放入一个物品时,该物品对下个请求可用,但然后就消失了(因此使用术语“flash”称之)。此段代码从 flash 中获取 post_id(1, 2, ...),并使用该 id 查找与之相关联的 blog 文章。
此段代码的第二行会把该文章的整个评论集合放到变量 @post_comment 中,该变量会在之后被传递至局部模板 _comments 中。
此段代码的最后一行把 post_id 放回 flash 中,这样可以为用户提交的下一条评论做好准备。
-
运行项目,验证一下评论能被动态更新了。
更上一层楼:应用视觉特效
之前在项目中加入的 script.aculo.us 库提供了视觉特效,可以使用这些特效来改善应用程序的外观和用户体验。在此,我们将应用一个特效来高亮 blog 中的最新评论。在应用该特效之后,您就可以方便的替换并尝试 script.aculo.us 库中的其他特效了。
-
打开文件 _comments.rhtml,将行 <li> <%= comment.comment %><br> 替换成下面的代码块:
| 代码示例 4:判定最新评论的代码 |
<% if @post_comments.index(comment) == @post_comments.length-1 %> <li id="new_comment"><%=h comment.comment %><br>
<% else%> <li><%=h comment.comment %><br> <% end %>
|
此段代码的第一行判断一个评论是否是最新的。若是,则在代码的第二行给该评论分配 id new_comment,因为该评论是我们想要应用视觉特效的。
-
切换至 post_comment.rhtml 文件,并添加下面这行高亮新评论的代码:
page[:new_comment].visual_effect :highlight
-
选择“文件”>“全部保存”,然后刷新浏览器。添加一条评论,同时留意该新评论是被如何简明地高亮的。
图 1:带有高亮显示的评论模型视图

更多内容
>> 更多 NetBeans Ruby 文档