奥门新浦京官方网站在Ruby on Rails中使用AJAX的教程

本文由码农网 –
王国峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

如果没有听说过
Rails,那么欢迎您外星旅行归来,近几年大概只有那个地方没有听说过 Ruby on
Rails 了。Rails
最吸引人的地方是能够很快地建立功能完备的应用程序并运行起来。Rails 为
Ajax 而内置集成的 Prototype.js 库可以轻松快速地创建所谓的富 Internet
应用程序。

AJAX的全称是Asynchronous JavaScript and XML(异步的 JavaScript 和
XML)。

介绍

聊天应用程序在网上非常常见。开发人员在构建这类应用程序时的选择也很多。这篇文章介绍了如何实现基于PHP-AJAX的聊天应用程序,并且不需要刷新页面就可以发送和接收消息。

本文将逐步引导您创建 Rails 应用程序。然后深入分析如何利用 Ajax
特性编写从服务器上读写数据的 JavaScript 代码。
从容起步 Ajax 之旅——Ajax 技术资源中心

AJAX不是新的编程语言,而是一种使用现有标准的新方法。ajax是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下。

核心逻辑

在定义应用程序的核心功能之前,先来看一看聊天应用程序的基本外观,如以下截图所示:

奥门新浦京官方网站 1

通过聊天窗口底部的输入框输入聊天文本。点击Send按钮,就开始执行函数set_chat_msg。这是一个基于Ajax的函数,因此无需刷新页面就可以将聊天文本发送到服务器。程序在服务器中执行chat_send_ajax.php以及用户名和聊天文本。

//
// Set Chat Message
//

function set_chat_msg()
{
    if(typeof XMLHttpRequest != "undefined")
    {
        oxmlHttpSend = new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
       oxmlHttpSend = new ActiveXObject("Microsoft.XMLHttp");
    }
    if(oxmlHttpSend == null)
    {
       alert("Browser does not support XML Http Request");
       return;
    }

    var url = "chat_send_ajax.php";
    var strname="noname";
    var strmsg="";
    if (document.getElementById("txtname") != null)
    {
        strname = document.getElementById("txtname").value;
        document.getElementById("txtname").readOnly=true;
    }
    if (document.getElementById("txtmsg") != null)
    {
        strmsg = document.getElementById("txtmsg").value;
        document.getElementById("txtmsg").value = "";
    }

    url += "?name=" + strname + "&msg=" + strmsg;
    oxmlHttpSend.open("GET",url,true);
    oxmlHttpSend.send(null);
}

PHP模块从Query
String(查询字符串)中接收表单数据,更新到命名为chat的数据库表中。chat数据库表有命名为IDUSERNAMECHATDATEMSG的列。ID字段是自动递增字段,所以这个ID字段的赋值将自动递增。当前的日期和时间,会更新到CHATDATE列。

require_once('dbconnect.php');

db_connect();

$msg = $_GET["msg"];
$dt = date("Y-m-d H:i:s");
$user = $_GET["name"];

$sql="INSERT INTO chat(USERNAME,CHATDATE,MSG) " .
      "values(" . quote($user) . "," . 
      quote($dt) . "," . quote($msg) . ");";

      echo $sql;

$result = mysql_query($sql);
if(!$result)
{
    throw new Exception('Query failed: ' . mysql_error());
    exit();
}

为了接收来自数据库表中所有用户的聊天消息,timer函数被设置为循环5秒调用以下的JavaScript命令,即每隔5秒时间执行get_chat_msg函数。

var t = setInterval(function(){get_chat_msg()},5000);

get_chat_msg是一个基于Ajax的函数。它执行chat_奥门新浦京官方网站,recv_ajax.php程序以获得来自于数据库表的聊天信息。在onreadystatechange属性中,另一个JavaScript
函数get_chat_msg_result被连接起来。在返回来自于数据库表中的聊天消息的同时,程序控制进入到get_chat_msg_result函数。

//
// General Ajax Call
//

var oxmlHttp;
var oxmlHttpSend;

function get_chat_msg()
{
    if(typeof XMLHttpRequest != "undefined")
    {
        oxmlHttp = new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
       oxmlHttp = new ActiveXObject("Microsoft.XMLHttp");
    }
    if(oxmlHttp == null)
    {
        alert("Browser does not support XML Http Request");
       return;
    }

    oxmlHttp.onreadystatechange = get_chat_msg_result;
    oxmlHttp.open("GET","chat_recv_ajax.php",true);
    oxmlHttp.send(null);
}

在chat_recv_ajax.php程序中,来自于用户的聊天消息会通过SQL select命令进行收集。为了限制行数,在SQL查询中还给出了限制子句(limit 200),即要求聊天数据库表中的最后200行。所获得的消息再返回给Ajax函数,用于在聊天窗口中显示内容。

require_once('dbconnect.php');

db_connect();

$sql = "SELECT *, date_format(chatdate,'%d-%m-%Y %r') 
as cdt from chat order by ID desc limit 200";
$sql = "SELECT * FROM (" . $sql . ") as ch order by ID";
$result = mysql_query($sql) or die('Query failed: ' . mysql_error());

// Update Row Information
$msg="";
while ($line = mysql_fetch_array($result, MYSQL_ASSOC))
{
   $msg = $msg . "" .
        "" .
        "";
}
$msg=$msg . "<table style="color: blue; font-family: verdana, arial; " . 
  "font-size: 10pt;" border="0">
  <tbody><tr><td>" . $line["cdt"] . 
  " </td><td>" . $line["username"] . 
  ": </td><td>" . $line["msg"] . 
  "</td></tr></tbody></table>";

echo $msg;

数据准备就绪的同时,JavaScript函数会收集来自于PHP接收到的数据。这些数据将被安排置于DIV标签内。oxmlHttp.responseText会保留从PHP程序接收到的聊天消息,并复制到DIV标签的document.getElementById(“DIV_CHAT”).innerHTML属性。

function get_chat_msg_result(t)
{
    if(oxmlHttp.readyState==4 || oxmlHttp.readyState=="complete")
    {
        if (document.getElementById("DIV_CHAT") != null)
        {
            document.getElementById("DIV_CHAT").innerHTML =  oxmlHttp.responseText;
            oxmlHttp = null;
        }
        var scrollDiv = document.getElementById("DIV_CHAT");
        scrollDiv.scrollTop = scrollDiv.scrollHeight;
    }
}

下面的SQL CREATE
TABLE命令可用于创建名为chat的数据库表。所有由用户输入的信息都会进入到数据库表中。

create table chat( id bigint AUTO_INCREMENT,username varchar(20), 
chatdate datetime,msg varchar(500), primary key(id));

什么是 Ajax?Ajax(Asynchronous JavaScript and
XML)是一种编程技术,它允许结合 XML 和 JavaScript 用于 Web
应用程序,从而打破页面刷新的范式,使您的用户快速方便的与 Web
应用程序交互。

ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

兴趣点

这段用于实现聊天应用程序的代码非常有意思。它可以改进成为一个完全成熟的HTTP聊天应用程序。创建该应用程序的逻辑也非常简单。即使是初学者理解起来也不会有任何困难。

您想了解如何构建基于 Ajax 的应用吗?developerWorks
中国网站上有非常多的关于 Ajax 的文章、教程和技巧,通过“Ajax
技术资源中心”,您可以非常快捷地找到能帮助您完成与 Ajax
相关的应用开发的技术参考资源。

ajax是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换。ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。而传统的网页(不使用ajax)如果需要更新内容,必须重载整个网页面。

许可证

这篇文章,以及任何相关的源代码和文件,都获得了The Code Project Open
License (CPOL)的许可。

关于 Rails 的一点说明

奥门新浦京官方网站 2

那么到底什么是 Rails 呢?Rails 是建立在 Ruby 编程语言上的一种 Web
应用程序平台。Ruby 存在大约有 10 年了。和 Perl 以及 Python
一样,它也是一种开放源码的敏捷编程语言,完全支持面向对象编程。

在Web应用开发过程中,业界对前后端的分界线似乎一直都没有确定的概念,不过大多数人以浏览器作为前后端的分界线。将浏览器中为用户进行页面展示的部分称为前端,而将运行于服务器,为前端提供业务逻辑和数据准备的所有代码统称为后端。

Rails 作为一种应用程序框架,强调使用正确的 Web
应用程序模式,即模型-视图-控制器(MVC)。在这里,系统的模型部分通常用一组映射到数据库表的
ActiveRecord 对象表示。控制器部分是一个 Ruby
类,其方法可以对模型执行各种操作。视图一般就是通过 ERB 模板(ERB 是 Ruby
内置的文本模板包)生成的超文本标记语言代码(HTML),形式上和 PHP 或
JavaServer Pages(JSP)代码生成的 HTML
类似。视图也可以是可扩展标记语言(XML)、文本、JavaScript
代码、图片或者其他东西。

奥门新浦京官方网站 3

用户从 Rails Web 应用程序请求页面时,URL
通过路由系统发送,后者将请求发送给控制器。控制器从模型请求数据并发送给视图完成格式化。

虽然前后端分离在数年前就已经开始受到关注,但很多人对它却是只闻其声,未见其形,所以对它产生了一些误解,误以为前后段分离只是一种Web应用的开发模式,只要在Web应用的开发期进行了前后端开发工作的分工就是前后端分离。

创建 Rails 应用程序时,系统自动生成一些目录和基本文件。包括随系统安装的
JavaScript 文件目录(包括 Prototype.js
库)、视图、模型和控制器目录,甚至还有存放从其他开发人员那里下载的插件的目录。

其实并非如此,准确的说,前后端分离并不只是开发模式,而是Web应用的一种架构模式。在开发期,前后端工程师可以通过约定好交互接口,实现并行开发;在运行期,前后端分离模式需要对Web应用进行分离部署,前后端之间使用HTTP请求进行交互。

开始使用 Rails

奥门新浦京官方网站 4

创建 Rails 应用程序最简单的办法就是使用一个预先打好包的 Rails
系统。如果平台是 Microsoft? Windows?,建议您使用 Instant Rails。在
Macintosh 机器上我非常喜欢 Locomotive 2 应用程序。这些应用程序都包括
Rails 框架、Ruby 语言、Web 服务器和
MySQL。下载了这么多东西(确实是这样)之后,创建 Rails
应用程序仅仅是举手之劳了。

一、JSON解析

本文将创建一个新的菜谱应用程序,称为Recipe,只需要一个表。清单 1 显示了
Recipe 应用程序的数据库迁移。
清单 1. 数据库迁移

JSON(JavaScript Object Notation)
是一种轻量级的数据交换格式。JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。简单地说,JSON
可以将 JavaScript
对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从
Web 客户机传递给服务器端程序。

class CreateRecipes < ActiveRecord::Migration
 def self.up
 create_table ( :recipes, :options => 'TYPE=InnoDB' ) do |t|
 t.column :name, :string, :null => false
 t.column :description, :text, :null => false
 t.column :ingredients, :text, :null => false
 t.column :instructions, :text, :null => false
 end
 end

 def self.down
 drop_table :recipes
 end
end

二、Ajax接口调用

数据库中只有一个表:recipes。包含五个字段:name、description、ingredients、instructions,还有一个字段是
Rails 基础设施自动维护的唯一标识符。

前后端分离意味着,前后端之间使用 JSON 来交流,两个开发团队之间使用 API
作为契约进行交互, 通过JSON字符串,然后在异步应用程序中将字符串从 Web
客户机传递给服务器端程序。这部分学习的就是如何从前台向后台发起一个Ajax请求,最后得到服务器返回的数据响应之后,进行前端页面的更新。

建立好数据库表之后,接下来就要为它包装一个 ActiveRecord 对象。该对象如
清单 2 所示。
清单 2. Recipe 模型

三、php后台

class Recipe < ActiveRecord::Base
 validates_presence_of :name
 validates_presence_of :description
 validates_presence_of :ingredients
 validates_presence_of :instructions
end

奥门新浦京官方网站 5

ActiveRecord
基类负责所有基本的数据库访问:查询表、插入、更新和删除记录。这里只要为每个字段增加验证就够了。我告诉
Rails 每个字段不能为空。

PHP是一种流行的通用脚本语言,特别适合于web开发。php语言具有以下特点:

Ajax 表单

1、跨平台,性能优越,和很多免费的平台结合非常省钱,比如LAMP(Linux
/Apache/Mysql/PHP)或者FAMP(FreeBSD/Apache/Mysql/PHP)结合,或者数据应用够大可以考虑换
PostgreSQL或者Oracle,支持N种数据库。(N >= 10)

创建 Recipe 应用程序的第一步是向数据库中添加菜谱。首先介绍在 Rails
中创建基本 HTML 表单的标准方法。如 清单 3 中的 RecipesController
类所示。
清单 3. Recipes_controller.rb

2、语法简单,如果有学习C和Perl的很容易上手,并且跟ASP有部分类似。有成熟的开发工具,比如NuPHPed,或者Zend
Studio等等,再Linux平台下可以使用Eclipse等等。

class RecipesController < ApplicationController
 def add
 @recipe = Recipe.new
 if request.post?
 @recipe.name = params[:recipe][:name]
 @recipe.description = params[:recipe][:description]
 @recipe.ingredients = params[:recipe][:ingredients]
 @recipe.instructions = params[:recipe][:instructions]
 @recipe.save
 end
 end
end

3、目前主流技术都支持,比如WebService、Ajax、XML等等,足够应用。

只有一个方法 add,它首先创建一个空的 Recipe
对象。然后当客户机发出请求时添加参数并保存数据。

4、有很多成熟的框架,比如支持MVC的框架:phpMVC,支持类似ASP.net的事件驱动的框架:Prado,支持类似Ruby
On Rails的快速开发的框架:Cake等等,足够满足你的应用需求。

该页面的 ERB 模板如 清单 4 所示。
清单 4. Add.rhml

5、PHP
5已经有成熟的面向对象体系,能够适应基本的面向对象要求。适合开发大型项目。

<html>
 <body>
<%= error_messages_for 'recipe' %><br/>
<%= start_form_tag %>
<table>
<tr><td>Name</td>
<td><%= text_field :recipe, :name %></td></tr>
<tr><td>Description</td>
<td><%= text_area :recipe, :description, :rows => 3 %></td></tr>
<tr><td>Ingredients</td>
<td><%= text_area :recipe, :ingredients, :rows => 3 %></td></tr>
<tr><td>Instructions</td>
<td><%= text_area :recipe, :instructions, :rows => 3 %></td></tr>
</table>
<%= submit_tag 'Add' %>
<%= end_form_tag %>
 </body>
</html>

这部分主要学习的如何搭建一个php服务器,掌握PHP的基本语法,通过php生成一个动态网页,掌握如何使用php完成一个标准化的接口,最终返回JSON数据给前台。

页面首先显示 recipe 对象的错误消息。如果用户发布的数据没有通过 Recipe
模型对象的验证就会设置这些消息。然后依次为 <form> 标记、每个字段的
text_field 和 text_area 项、<submit> 标记和表单末尾。

四、数据库

这是非常标准的
Rails。安全可靠,可用于各种浏览器,清晰地映射到为客户机创建的
HTML。但我需要的是 Web 2.0,就是说 Ajax。那么,该如何修改呢?

奥门新浦京官方网站 6

控制器端的 add() 方法彻底变了,如 清单 5 所示。
清单 5. Recipes_controller.rb

数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制
所保存的数据。我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢。

class RecipesController < ApplicationController
 def add
 end

 def add_ajax
 Recipe.create( { :name => params[:recipe][:name],
 :description => params[:recipe][:description],
 :ingredients => params[:recipe][:ingredients],
 :instructions => params[:recipe][:instructions] } )
 end
end

MySQL是一个关系型数据库管理系统,由瑞典MySQL
AB公司开发,目前属于Oracle公司。MySQL是一种关联数据库管理系统,关联数据库将数据保存在
不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。

add() 方法不再做任何事,因为有一个新的方法 add_ajax()
处理客户机返回的数据。

• Mysql是开源的,所以你不需要支付额外的费用。

对于模板来说,不需要做大的修改,如 清单 6 所示。
清单 6. add.rhtml 的开始部分

• Mysql支持大型的数据库。可以处理拥有上千万条记录的大型数据库。

<html>
 <head>
 <%= javascript_include_tag :defaults %>
 </head>
 <body>
 <div id="counter"></div>
<%= form_remote_tag :url => { :action => 'add_ajax' },
 :complete => 'document.forms[0].reset();',
 :update => 'counter' %>
<table>
<tr><td>Name</td>

• MySQL使用标准的SQL数据语言形式。

文件开始在 HTML 中增加了 head 部分,其中包含对 Rails 默认 JavaScript
文件的引用。这就是 Prototype.js 系统,完成 Ajax 工作的大部分。


Mysql可以允许于多个系统上,并且支持多种语言。这些编程语言包括C、C++、Python、Java、Perl、PHP、Eiffel、Ruby和Tcl等。

然后添加了 <div> 标记 counter,保存从 Ajax
请求返回的结果。并不是非常必要,但给用户一些反馈也不错。

• Mysql对PHP有很好的支持,PHP是目前最流行的Web开发语言。

最后,将原来的 start_form_tag 改为
form_remote_tag。form_remote_tag 有几个参数,其中最重要的是
url,它指定向何处发送数据。第二个是一个完整的处理程序,其中的 JavaScript
代码在 Ajax 请求完成时执行。这里重置表单以便让用户输入新的菜谱。然后使用
update 参数告诉 Rails 把 add_ajax 动作的输出发送到何处。


MySQL支持大型数据库,支持5000万条记录的数据仓库,32位系统表文件最大可支持4GB,64位系统支持最大的表文件为8TB。

add_ajax() 方法还需要一个模板。如 清单 7 所示。
清单 7. Add_ajax.rhtml

这部分主要学习的是数据中的增删改查操作,最后通过php访问数据中的数据,然后通过响应的处理,发挥给前台使用。

<%= Recipe.find(:all).length %> recipes now in database

五、Ajax跨域

如此而已。但并不完全是。这仅仅是从标准 HTML 表单迁移到 Rails 中的 Ajax
表单。图 1 显示了准备提交的 Ajax 表单。
图 1. Ajax 表单

由于在工作中需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问。

奥门新浦京官方网站 7

解决方式一:

接下来是更加动态的交互,比如使用 Ajax 动态搜索。

“XHR2” 全称 “XMLHttpRequest Level2”
是HTML5提供的方法,对跨域访问提供了很好的支持,并且还有一些新的功能。

Ajax 动态搜索

* IE10以下的版本都不支持

Prototype.js
提供了观察页面上的字段和表单的功能。我利用这种功能观察一个文本字段,可在其中输入部分菜谱名。然后运行
RecipesController 的搜索方法,输出放在文本字段下方的 <div>
标记中。首先从更新的 RecipesController 开始,如 清单 8 所示。
清单 8. Recipes_controller.rb

* 只需要在服务器端头部加上下面两句代码:

class RecipesController < ApplicationController
...
 def index
 end

 def search_ajax
 @recipes = Recipe.find( :all,
 :conditions => [ "name LIKE ?",
 "%#{params[:recipe][:name]}%" ] )
 render :layout=>false 
 end
end
header( "Access-Control-Allow-Origin:*" );
header( "Access-Control-Allow-Methods:POST,GET" );

index() 方法呈现 HTML 表单。search_ajax()
方法根据搜索参数查找菜谱并把数据发送给 ERB 模板格式化。index.rtml 模板如
清单 9 所示。
清单 9. Index.rhtml

解决方式二:

<html>
<head>
<%= javascript_include_tag :defaults %>
</head>
 <body>
<%= form_tag nil, { :id => 'search_form' } %>
<%= text_field 'recipe', 'name' %>
<%= end_form_tag %>

<div id="recipe">
</div>

<%= observe_form :search_form, :frequency => 0.5,
 :update => 'recipe',
 :url => { :action => 'search_ajax' } %> 
 </body>
</html>

JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script
tags返回至客户端,通过javascript
callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

在 清单 9 的开头同样包括了 JavaScript 库。然后创建一个具有搜索字段和
<div> 标记的 form 表单用来保存搜索返回的数据。最后调用
observe_form() 辅助方法,它创建 JavaScript
代码观察表单的变化,并把表单数据发送到 search_ajax()
方法。然后将该方法的结果放到 recipe <div> 中。

由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。

search_ajax.rhtml 表单的代码如 清单 10 所示。
清单 10. Search_ajax.rhtml

总结

<% @recipes.each { |r| %>
<h1><%= r.name %></h1>
<p><%= r.description %></p>
<% } %>

以上所述是小编给大家介绍的Ajax异步请求技术实例讲解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

由于搜索结果可能有多项,循环遍历菜谱列表并输出其名称和说明。

您可能感兴趣的文章:

  • Vue form
    表单提交+ajax异步请求+分页效果
  • ajax异步请求详解
  • AJAX实现简单的注册页面异步请求实例代码
  • 基于JQuery的$.ajax方法进行异步请求导致页面闪烁的解决办法
  • SpringMVC环境下实现的Ajax异步请求JSON格式数据
  • jquery的ajax异步请求接收返回json数据实例
  • ajax的工作原理以及异步请求的封装介绍
  • dojo学习第二天
    ajax异步请求之绑定列表

当在浏览器中打开该站点并在地址栏中输入 apple
的时候,我找到了苹果馅饼的做法,如 图 2 所示。
图 2. Ajax 动态搜索

奥门新浦京官方网站 8

这就是最简单的实现。但如果希望进一步了解苹果馅饼该如何做?可以使用 Ajax
在需要时动态获得配料和做法吗?很高兴您这样问!当然能!


在命令中增加内容

有时候,让用户选择下载更多的信息而不是生硬地把信息堆到页面上更加友好。传统上,Web
应用程序开发人员使用隐藏的 <div>
标记包含信息,当用户要求这些资料时再显示出来。Rails
提供了一种更优美的方法,可以在需要的时候使用 Ajax 请求数据。

清单 11 中的菜单模板增加了 link_to_remote() 辅助方法调用。
清单 11. Search_ajax.rhtml

<% @recipes.each { |r| %>
<h1><%= r.name %></h1>
<p><%= r.description %></p>
<div id="extra_<%= r.id %>"></div>
<%= link_to_remote 'Extra',
 :url => { :action => 'get_extra_ajax', :id => r.id }, 
 :update => "extra_#{r.id}" %> 
<% } %>

link_to_remote() 在页面中添加 JavaScript 代码和包含指定文本的
anchor(<a>)标记。客户单击该链接时,页面就会发出 Ajax
请求来获得新内容并替代原来的文本。

为了获得新的信息,必须为 RecipesController 添加一个 get_extra_ajax()
方法。如 清单 12 所示。
清单 12. Recipes_controller.rb

class RecipesController < ApplicationController
 ...
 def get_extra_ajax
 @recipe = Recipe.find( params[:id] )
 render :layout=>false 
 end
end

此外还需要一个模板 get_extra_ajax.rhtml 来格式化这些信息。清单 13
显示了该模板。
清单 13. Get_extra_ajax.rhtml

<blockquote><%= simple_format @recipe.ingredients
%></blockquote>
<p><%= simple_format @recipe.instructions %></p>

现在回到页面并输入 apple,将看到 图 3 所示的结果。
图 3. 增加了可以访问配料及做法的链接

奥门新浦京官方网站 9

单击该链接时,浏览器使用 Ajax 从 Web
服务器检索额外的资料并显示在那个位置。结果如 图 4 所示。
图 4. 菜谱的细节

奥门新浦京官方网站 10

如果有一个行项或细节类型的报告,这种 Ajax
模式非常方便,因为请求每个记录的细节可能非常耗时,最好在需要的时候再请求。此外这种技术也有助于节约屏幕资源。

可能最热门的 Web 2.0 特性是自动完成文本字段。否则 这趟 Ajax
之旅怎么能算完整呢?


自动完成字段

Rails 使得构建自动完成字段极其简单。首先要在 index.rhtml
模板中增加一些东西。修改后的版本如 清单 14 所示。
清单 14. 修改后的 index.rhtml

<html>
<head>
<%= javascript_include_tag :defaults %>
<style>
div.auto_complete {
 width: 300px; 
 background: #fff; 
} 
div.auto_complete ul { 
 border: 1px solid #888; 
 margin: 0px; 
 padding: 0px; 
 width: 100%; 
 list-style-type: none; 
} 
div.auto_complete ul li { 
 margin: 0px; 
 padding: 3px; 
} 
div.auto_complete ul li.selected { 
 background-color: #ffb; 
} 
div.auto_complete ul strong.highlight { 
 color: #800; 
 margin: 0px; 
 padding: 0px; 
} 
</style>
</head>
 <body>
<%= form_tag nil, { :id => 'search_form' } %>
<p><%= text_field 'recipe', 'name', :autocomplete => 'off' %></p>
<div class="auto_complete" id="recipe_name_auto_complete"></div> 
<%= auto_complete_field :recipe_name,
 :url => { :action=>'autocomplete_recipe_name' },
 :tokens => ',' %>
<%= end_form_tag %>
...

文件上方的级联样式表(CSS)部分用于自动完成字段的下拉列表。此外还对
text_field 略做修改关闭浏览器的自动完成机制。下拉列表中的项放在新增的
<div> 中,这些项将调用 auto_complete() 方法。auto_complete()
辅助方法创建客户端 JavaScript 代码调用服务器上的
autocomplete_recipe_name() 方法以及 recipe name 文本字段的当前内容。

RecipesController 的 autocomplete_recipe_name() 方法搜索该名称,如
清单 15 所示。
清单 15. Recipes_controller.rb

class RecipesController < ApplicationController
...
 def autocomplete_recipe_name
 @recipes = Recipe.find( :all,
 :conditions => [ "name LIKE ?",
 "%#{params[:recipe][:name]}%" ] )
 render :layout=>false 
 end
end

还需要一个 ERB 模板建立列表,如 清单 16 所示。
清单 16. Autocomplete_recipe_list.rb

<ul class="autocomplete_list"> 
<% @recipes.each { |r| %> 
<li class="autocomplete_item"><%= r.name %></li> 
<% } %> 
</ul>

自动完成系统查找一个 HTML 列表(<ul>),其中每个列表项都是一个
option。使用 index.rhtml 页面的 CSS (或者您提供的样式表)格式化。

为了查看自动完成的效果,在浏览器中打开页面,然后输入 test。我在 test
菜谱中加入了一些数据。结果如 图 5 所示。
图 5. 下拉自动完成列表

奥门新浦京官方网站 11

可以使用上下箭头键选择一个选项然后按 Enter
键选择。这样将把选择的内容复制到文本字段中。

非常灵活,感谢 Rails 体系结构,它使这很容易实现。

结束语

无需讳言,我喜欢
Rails。从使用它的那一刻起我就被它深深吸引了。就我所见,Web
的很多开发人员都被它吸引了。为什么不呢?Rails 使得创建高交互性的 Web
应用程序易如反掌。

即使您还没有开始编写 Rails 应用程序,我也建议您下载 Instant Rails 或
Locomotive 应用程序开始尝试一下。您将体会到很多乐趣,并学习到很多可用于
Java? PHP 或 Microsoft .NET 应用程序的东西。也许您会发现您希望一直编写
Rails 代码。

您可能感兴趣的文章:

  • Windows下Ruby on
    Rails开发环境安装配置图文教程
  • ruby on rails 代码技巧
  • 攻克CakePHP(PHP中的Ruby On
    Rails框架)图文介绍
  • 在阿里云 (aliyun) 服务器上搭建Ruby On
    Rails环境
  • CentOS中配置Ruby on
    Rails环境
  • win7安装ruby on
    rails开发环境
  • ruby on
    rails中Model的关联详解

发表评论

电子邮件地址不会被公开。 必填项已用*标注