FeaturesDocs & SupportCommunityBlogsPartners

在 Ruby on Rails 中使用 Ajax

在本教程中,我们将介绍在 NetBeans Ruby on Rails 项目中添加 Ajax 支持。教程示例展示了如何在 web 日志中动态地添加评论。

目录

教程需求
创建样例数据库
创建局部模板
添加 Ajax 支持
添加 RJS 实现动态更新
更上一层楼:应用视觉特效
  本页面的内容适用于 NetBeans IDE 6.0

教程需求

学习本教程需要以下技术和资源:

创建样例数据库

本教程基于另一篇教程构建 Rails 模型之间的关系。如果您完成了那篇教程,那么您可以将完成教程时生成的项目作为起点,直接进入下一节。否则,请您先下载 RubyWebLogModel.zip 文件,然后按照下面的步骤创建样例数据库。

 

注意:本教程使用 MySQL 数据库服务器。您可以参考安装和配置 Ruby 支持一文以获取有关如何在 Ruby 应用程序中使用 MySQL 数据库服务器的信息。该文档同样介绍了如何使用 JavaDB 数据库服务器作为替代。
  1. 打开一个命令行窗口。
  2. 如果 MySQL 数据库服务器尚未被启动,请先将其启动。
  3. 键入如下命令来创建开发数据库,并按“Enter”键。
    mysqladmin -u root -p create rubyweblog_development
    注意:如果 root 用户不要求密码,请省略 -p 参数。
  4. 在 IDE 中打开 rubyweblog 项目。

    注意:如果是初次打开或者创建 Ruby 项目,IDE 会检查您是否有除了绑定的 JRuby 软件之外其他的 Ruby 安装。如果有,IDE 会显示一个对话框,询问您选择使用哪个软件。若您想要使用绑定的 JRuby 解释器,选择 JRuby;或者您喜欢使用您自己的 Ruby 安装,那就选择您自己的安装。更多信息,请参考《安装和配置 Ruby》教程中的配置 IDE 使用您自己的 Ruby 安装一节。
  5. 如果您的数据库要求密码,请编缉 database.yml 文件,并在开发配置部分中提供密码。保存该文件。

    要快速访问 database.yml 文件,按 Alt+Shift+O(在 Mac 系统中按 Ctrl+Shift+O),在“文件名”文本框中键入 database.yml,然后按“Enter”键。
  6. 右键点击 rubyweblog 节点,选择“迁移数据库”>“到当前版本”。

    该操作会更新数据库以加入 posts 表和 comments 表。 迁移完成时会在“输出”窗口显示。
  7. 运行应用程序并发表一篇新文章。
  8. 点击“Permalink”,然后给该文章添加一条评论。

    可以发现当添加评论时,整个页面都被重新加载了。

创建局部模板

在当前的 rubyweblog 项目中,无论何时读者向页面添加评论,页面上的 blog 条目和所有评论都会被重新载入。更好的解决方案是使用 Ruby on Rails 框架中的 Ajax 支持来动态加载这些评论。作为使用 Ajax 的预先准备,需要创建局部模板来存储用于显示评论的代码。使用局部模板的好处是可以多次调用局部模板(显示 blog 中每个评论需要一次), 而无需渲染 blog 条目本身。

  1. 右键点击 rubyweblog 节点,选择“新建”>“RHTML File”。将文件命名为 _comments,并将其放置在 app\views\blog 文件夹中。

    IDE 会创建 _comments 文件,并将其在编辑区打开。 注意,局部模板的文件名使用下划线(_)开头,以区别于完全模板。

    当前,显示评论的代码在文件 show.rhtml 中。而在下一步,则会从 show.rhtml 中删除这部分代码,并将代码粘贴至局部模板 _comments.rhtml 中。
  2. 转至 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>
  3. 返回 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 显示的评论。
  4. 选择“文件”>“全部保存”,然后运行应用程序。

  5. 点击“Permalink”,然后给文章添加一条评论。

    此时,应用程序的表现和前面如出一辙。但它现在已被设计成可以开始使用 Ajax 支持了。

添加 Ajax 支持

在项目中添加 Ajax 支持的第一步是加入 JavaScript 库,Prototypescript.aculo.us。这些库是与 Ruby on Rails 绑定在一起的。Prototype 库提供了 Ruby on Rails 中 Ajax 实现的基础,而script.aculo.us 库则提供了视觉特效,可在应用程序中随意添加。

  1. 展开“Views”>“layouts”,然后打开 blog.rhtml 文件。
  2. 在包含 stylesheet_link_tag 的行下面,添加如下代码行:

    <%= javascript_include_tag :defaults %>

    此行代码会加入与 Ruby on Rails 绑定的 JavaScript 库:Prototype 和 script.aculo.us。下一步是创建 form_remote_tag,以触发 Ajax 动作。

  3. 打开 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 文件,删除该调用。
  4. 展开“Controllers”节点,打开 blog_controller.rb 文件。
  5. 滚动至 post_comment 动作,注释掉 redirect_to 调用。
    # redirect_to :action => 'show', :id => flash[:post_id]
    如果您现在就运行应用程序,并添加一条评论,则该评论不会被显示出来。您必须在下一步插入 Ruby JavaScript (RJS)模板来处理 XMLHTTPRequest。

添加 RJS 实现动态更新

最后的步骤是使用内建的 RJS 支持来动态更新 blog 上的评论。

  1. 在“Views”节点中,右键点击“blog”节点,选择“新建”->“Empty RJS Template”。

  2. 设置“文件名”为 post_comment,并将其仿真在 app\views\blog 文件夹中。
  3. 删除已有的页面对象,然后在该位置插入下面的页面对象。

    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 文件。
  4. 打开 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 中,这样可以为用户提交的下一条评论做好准备。

     

  5. 运行项目,验证一下评论能被动态更新了。

更上一层楼:应用视觉特效

之前在项目中加入的 script.aculo.us 库提供了视觉特效,可以使用这些特效来改善应用程序的外观和用户体验。在此,我们将应用一个特效来高亮 blog 中的最新评论。在应用该特效之后,您就可以方便的替换并尝试 script.aculo.us 库中的其他特效了。

  1. 打开文件 _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,因为该评论是我们想要应用视觉特效的。
  2. 切换至 post_comment.rhtml 文件,并添加下面这行高亮新评论的代码:

    page[:new_comment].visual_effect :highlight
  3. 选择“文件”>“全部保存”,然后刷新浏览器。添加一条评论,同时留意该新评论是被如何简明地高亮的。

    图 1:带有高亮显示的评论模型视图

    带有高亮显示的评论模型视图

更多内容

 

>> 更多 NetBeans Ruby 文档

Companion
Projects:
                  Powered by: