Rails 2.1 中的 AJAX



Ajax 代表**异步** **Ja**vaScript 和 **X**ML。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 的其他概念时,我们以图书馆为例。在那里,我们有一个名为subject的表,并且我们在迁移时添加了一些主题。到目前为止,我们还没有提供任何在该表中添加和删除主题的程序。

在本例中,我们将提供主题表的列表、显示和创建操作。如果您不了解前面章节中解释的图书馆信息系统,那么我们建议您先完成前面的章节,然后再继续学习 Rails 上的 AJAX。

创建控制器

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

C:\ruby\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

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

列表方法实现

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

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

显示方法实现

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

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

创建方法实现

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

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

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

创建视图

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

为列表方法创建视图

在/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 的关联使您可以轻松地遍历关系并获取此类信息。

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

List Subjects

为显示方法创建视图

在/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方法创建视图,因为我们使用的是部分而不是视图。在下一节中,我们将为创建方法创建一个部分。

添加 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参数告诉 Rails 的 Ajax 引擎根据其 id 更新哪个元素。在本例中,它是<ul>标记。

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

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

为创建方法创建部分

我们在添加主题时调用create方法,并且在此创建方法内部,我们使用了一个部分。在进行实际操作之前,让我们实现此部分

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

将以下代码添加到此文件中 -

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

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

Add Subject

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

广告