Rails 2.1 上的 AJAX

Ajax 代表 Asynchronous JavaScript 和 XML。Ajax 不是一项单一技术;它是一套由多种技术组成的技术。Ajax 包含以下内容 −

  • 用于网页标记的 XHTML
  • 用于样式的 CSS
  • 使用 DOM 进行动态显示和交互
  • 使用 XML 进行数据操作和交换
  • 使用 XMLHttpRequest 进行数据检索
  • JavaScript 作为将所有这些结合在一起的粘合剂

Ajax 使您无需刷新整个页面的内容即可检索网页数据。在基本的 Web 架构中,用户单击链接或提交表单。表单提交给服务器,然后服务器发回响应。响应随后在新页面上显示给用户。

当您与支持 Ajax 的网页交互时,它会在后台加载 Ajax 引擎。该引擎用 JavaScript 编写,其职责是与 Web 服务器通信并向用户显示结果。当您使用基于 Ajax 的表单提交数据时,服务器将返回一个包含服务器响应的 HTML 片段,并且仅显示新的或更改的数据,而不是刷新整个页面。

有关 AJAX 的完整详细信息,您可以阅读我们的 AJAX 教程

Rails 如何实现 Ajax

Rails 有一个简单、一致的模型来实现 Ajax 操作。浏览器呈现并显示初始网页后,不同的用户操作会导致它显示新网页(就像任何传统的 Web 应用程序一样)或触发 Ajax 操作 −

  • 一些触发器触发 −此触发器可能是用户单击按钮或链接、用户更改表单或字段中的数据,或者只是定期触发器(基于计时器)。

  • Web 客户端调用服务器 − JavaScript 方法 XMLHttpRequest 将与触发器相关的数据发送到服务器上的操作处理程序。数据可能是复选框的 ID、输入字段中的文本或整个表单

  • 服务器进行处理 − 服务器端操作处理程序(Rails 控制器操作)对数据执行某些操作并将 HTML 片段返回到 Web 客户端。

  • 客户端接收响应 − Rails 自动创建的客户端 JavaScript 接收 HTML 片段并使用它来更新当前页面 HTML 的指定部分,通常是 <div> 标签的内容。

这些步骤是在 Rails 应用程序中使用 Ajax 的最简单方法,但只需进行一些额外的工作,您就可以让服务器响应 Ajax 请求返回任何类型的数据,并且您可以在浏览器中创建自定义 JavaScript 来执行更多复杂的交互。

AJAX 示例

在讨论其余 Rails 概念时,我们以 Library 为例。那里有一个名为 subject 的表,我们在迁移时添加了一些主题。到目前为止,我们还没有提供任何在此表中添加和删除主题的程序。

在此示例中,我们将提供、列出、显示和创建主题表上的操作。如果您对前面章节中介绍的图书馆信息系统没有任何理解,那么我们建议您先完成前面的章节,然后继续使用 AJAX on Rails。

创建控制器

让我们为主题创建一个控制器。它将按如下方式完成 −

C:
uby\library> ruby​​ script/generate controller Subject

此命令创建一个控制器文件 app/controllers/subject_controller.rb。在任何文本编辑器中打开此文件并修改它以包含以下内容 −

class SubjectController < ApplicationController
   layout 'standard'
   def list
   end
   def show
   end
   def create
   end
end

现在,我们将以前面章节中给出的相同方式讨论所有这些函数的实现部分。

list 方法实现

def list
@subjects = Subject.find(:all)
end

这与前面解释的示例类似,将用于列出数据库中可用的所有主题。

show 方法实现

def show
    @subject = Subject.find(params[:id])
end

这也与前面解释的示例类似,将用于显示与传递的 ID 相对应的特定主题。

create 方法实现

def create
   @subject = Subject.new(params[:subject])
      
   if @subject.save
      render :partial => 'subject', :object => @subject
   end
end

这部分有点新。这里我们没有将页面重定向到任何其他页面;我们只是渲染更改的部分而不是整个页面。

只有在使用 partial 时才会发生这种情况。我们不编写完整的视图文件,而是在 /app/view/subject 目录中编写一个部分。我们稍后会看到它。首先,让我们为其他方法创建视图文件。

创建视图

现在我们将为除 create 方法之外的所有方法创建视图文件,我们将为其创建部分。

为 list 方法创建视图

在 /app/view/subject 中创建一个文件 list.rhtml 并使用以下代码填充它。

<h1>Listing Subjects</h1>
<ul id="subject_list">
   <% @subjects.each do |c| %>
   <li><%= link_to c.name, :action => 'show', :id => c.id %>
   <%= "(#{c.books.count})" -%></li>
   <% end %>
</ul>

在这里,您将遍历 @subjects 数组并输出一个 <li> 元素,其中包含指向数组中每个项目所引用主题的链接。此外,您还将在括号内输出该特定主题的书籍数量。Rails 的关联使您可以轻松地逐步了解关系并获取此类信息。

现在,尝试使用 http://localhost:3000/subject/list 浏览您的主题列表。它将向您显示以下屏幕。

List Subjects

为 show 方法创建视图

在 /app/view/subject 中创建一个文件 show.rhtml 并使用以下代码填充它。

<h1><%= @subject.name -%></h1>
<ul>
   <% @subject.books.each do |c| %>
   <%= link_to c.title, :controller => 
      "book", :action => "show",:id => c.id -%>
   <% end %>
</ul>

现在,尝试单击任何主题,您将找到该主题下所有可用书籍的列表。

create 方法创建视图

我们不会为 create 方法创建视图,因为我们使用的是 partial 而不是 view。在下一节中,我们将为 create 方法创建一个部分。

添加 Ajax 支持

要在 Rails 应用程序中获得 Ajax 支持,您需要在布局中包含必要的 JavaScript 文件。Rails 捆绑了几个库,使使用 Ajax 变得非常容易。两个库 - prototypescript.aculo.us 非常受欢迎。

要向应用程序添加 Prototype 和 script.aculo.us 支持,请打开 app/views/layouts 中的 standard.rhtml 布局文件,在 </head> 标记之前添加以下行,然后保存更改 −

<%= javascript_include_tag :defaults %>

这包括模板中的 Prototype 和 script.aculo.us 库,因此可以从任何视图访问它们的效果。

现在,在 app/views/subject/list.rhtml 的底部添加以下代码。

<p id="add_link"><%= link_to_function("Add a Subject",
   "Element.remove('add_link'); Element.show('add_subject')")%></p>
<div id="add_subject" style="display:none;">
   <% form_remote_tag(:url => {:action => 'create'},
      :update => "subject_list", :position => :bottom,
      :html => {:id => 'subject_form'}) do %>
      Name: <%= text_field "subject", "name" %>
   <%= submit_tag 'Add' %>
   <% end %>
</div>

我们使用 link_to_function 而不是 link_to 方法,因为 link_to_function 方法使您能够利用 Prototype JavaScript 库的强大功能来执行一些简洁的 DOM 操作。

第二部分是创建 add_subject <div>。请注意,您使用 CSS display 属性将其可见性设置为默认隐藏。前面的 link_to_function 将更改此属性并向用户显示 <div>,以便用户输入添加新主题所需的输入。

接下来,您将使用 form_remote_tag 创建 Ajax 表单。此 Rails 帮助程序类似于 start_form_tag 标记,但此处使用它来让 Rails 框架知道它需要为此方法触发 Ajax 操作。 form_remote_tag 和 start_form_tag 一样,也接受 :action 参数。

您还有两个附加参数 − :update:position

  • :update 参数根据元素的 id 告诉 Rails 的 Ajax 引擎要更新哪个元素。在本例中,它是 <ul> 标签。

  • :position 参数告诉引擎将新添加的对象放置在 DOM 中的何处。您可以将其设置为无序列表的底部 (:bottom) 或顶部 (:top)。

接下来,像以前一样创建标准表单字段和提交按钮,然后使用 end_form_tag 结束所有内容以关闭 <form> 标签。确保内容在语义上正确且是有效的 XHTML。

为 create 方法创建部分

我们在添加主题时调用 create 方法,并且在此 create 方法中,我们使用一个部分。在实际操作之前,让我们先实现此 partial

在 app/views/subject 下,创建一个名为 _subject.rhtml 的新文件。请注意,所有部分都以下划线 (_) 开头命名。

在此文件中添加以下代码 −

<li id="subject_<%= subject.id %>">
   <%= link_to subject.name, :action => 'show', :id => subject.id %>
   <%= "(#{subject.books.count})" -%>
</li>

现在您已完成,可以轻松添加多个主题,而无需在添加每个主题后等待页面刷新。现在,尝试使用 http://localhost:3000/subject/list 浏览您的主题列表。它将显示以下屏幕。尝试添加一些主题。

添加主题

当您按下添加按钮时,主题将添加到所有可用主题的底部,您不会有页面刷新的感觉。