3.2. Ajax Links

现在我们既然有了这么帅气的页面,不如我们加点Ajax效果进去吧!修改下index.rhtml模板:
InBlock.gif<%= link_to_remote  "Check Time"
InBlock.gif    :update => 'current_time', 
InBlock.gif    :url    => { :action => 'get_time' } %> 
InBlock.gif<div id= "current_time"></div>
这次改变是将link_to换成了link_to_remote, 添加了一个新的选项, :update. :update后面跟的的是HTML的标签元素的ID值,Ajax的回应会插入到这个标签中,这个例子中使用了DIV, 那么生成的HTML大概是这样:
<a href="#" 
   Ajax.Updater('current_time', '/chapter3/get_time', 
               {asynchronous:true, evalScripts:true}); 
            return false;">Check Time </a> 
< div  id ="current_time" > </div>
看看这段生成的HTML代码, 你会发现这里用到了Prototype的Ajax.Updater方法,所有的Rails中的Ajax helper实现途径都一样:都是在HTML模板中插入Ruby方法,生成Javascript代码,调用Prototype.
 
Ajax链接的核心机制就是 helper要在最后的 false了。
=====================================================
tip: 你也许已经注意到这里生成了一个HTML链接:href="#".从技术上来讲,这种“不链接到任何地方”的方法在实践中使用很不好的。如果用户浏览器屏蔽了Javascript, 或者一个搜索引擎正在索引页面,这个链接就变得没有意义了。所以无论何时,有可能的话,最好提供一个有用的链接,给没有Ajax支持的浏览器提供一条退路。
-
 
 
3.2.1. Callbacks
继续前进。link_to_remote提供了一种显示调用信号的方法。这样你可以在Javascript代码执行Ajax请求的生命周期中使用这个信号。例如:
<%= link_to_remote "Check Time", 
    :update => 'current_time', 
    :url    => { :action => 'get_time' }, 
    :before => "$('current_time').update('Loading...')" %> 
< div  id ="current_time" > </div>
加上了:before这个选项后,当点击链接之后,结果返回之前,在current_time这个标签中的内显示"loading..."这么做会让用户感觉到这个链接点击之后在工作,这种显示调用的信号可以在请求的生命周期中每个阶段使用。常见的有:before, :success, 和:failure.你可以对多个阶段的信号加以描述,来处理不同的响应情况。常用的有加载指示和错误处理显示。如下例:
<%= link_to_remote "Check Time", 
    :update   => 'current_time', 
    :url      => { :action => 'get_time' }, 
    :before   => "$('indicator').show(  )", 
    :success  => "$('current_time').visualEffect('highlight')", 
    :failure  => "alert('There was an error. ')", 
    :complete => "$('indicator').hide(  )" %> 
<span id="indicator" style="display: none;">Loading...</span> 
<div id="current_time"></div>
在这个例子中,:before后面的代码说明在Ajax请求开始时,显示"Loading..."如果请求成功(意思是HTTP状态代码是200), :success在current_time这个标签内容上使用视觉效果。否则,:failure执行,给用户一个警示信息。对于任意一种情况(成果或失败),:complete 用来管理"Loading"元素是否隐藏。整套的这种可用的callback列表如表3-1所示
 
这是我们第一次见到Prototype的hide()和show()方法,借此机会我们可以来探讨一个问题:通过 Javascript动态的显示一个元素该怎么做? 必须在CSS中定义display: none的属性,相反在外部的stylesheet中定义就会不起作用。例如下面的代码是不会工作的:
< style  type ="text/css" > 
  #indicator { display: none; } 
</style> 
< div  id ="indicator" >Hidden DIV </div> 
< script  type ="text/javascript" > 
  $("indicator").show(  ); // won't work 
</script>
下面的代码会正常工作:
< div  id ="indicator"  style ="display: none" >Hidden DIV </div> 
< script  type ="text/javascript" > 
  $("indicator").show(  ); // will work 
</script> 
用同样的规则来请求任意一个JavaScript方法会改变元素的显示属性,例如Prototype的toggle()方法和script.aculo.us的可视化效果。通常情况下,把CSS规则放在外面,但是display: none是一个例外。
 
Table 3-1. Ajax helper的callback和相应情况的属性
------------------------------------------------------------------------------------------------------------------------
Helper callback      |     Prototype callback |            状态         |                            描述                        |
------------------------------------------------------------------------------------------------------------------------
         :before          |                                     |                             |       请求对象还没有创建完毕         |
-----------------------------------------------------------------------------------------------------------------------
        :after              |                                     |     0(未初始化)   |  请求对象的open()方法未被调用   |
------------------------------------------------------------------------------------------------------------------------
       :loading           |   onLoading                 |    1(正在加载)    |  请求对象的send()方法未被调用    |
------------------------------------------------------------------------------------------------------------------------
       :loaded            |    onLoaded                 |    2(加载完毕)    |             请求已完成初始化               |
------------------------------------------------------------------------------------------------------------------------
    :interactive         |     on Interactive         |    3(交互)            |               正在接收响应                     |
------------------------------------------------------------------------------------------------------------------------
    :success              |    onSuccess               |                             |     响应就绪并且状态在200的范围 |
------------------------------------------------------------------------------------------------------------------------
    :failure                |   onFailure                 |                             | 响应就绪但是状态不在200的范围   |
------------------------------------------------------------------------------------------------------------------------
    :complete           |  onComplete             |   4(完成)              |                           响应就绪                  |
------------------------------------------------------------------------------------------------------------------------
 
3.2.2 Other Options
除了callback之外,link_to_remote还有另外一些选项来指定它的行为。首先,它也支持和link_to选项里面的:method和:confirm功能。
 
:condition选项和:confirm一样:允许你有选择的执行请求,这是基于一些Javascript的功能。例如:
<li><%= check_box_tag 'get_time' %> get time</li>
<%= link_to_remote "get time", 
    :condition => "$('get_time').checked", 
    :url       => { :action => 'get_time' },
    :update =>"current_time",
    :before=> "$('indicator').show()",
    :success=>"$('current_time').visualEffect('highlight')",
    :complete=>"$('indicator').hide()"%>
<span id="indicator" style="display: none">Loading...</span>
<div id="current_time"></div>
 
当点击链接后,:condition 中的表达式会执行,如果执行的返回结果是true, 那么请求继续执行(在这个case中,checkbox被选中即返回true)。
 
:submit选项:允许你模仿表单提交,当你提供了一个页面元素的ID时,这个元素的内容会和请求一起发送出去,这意思就是说你没必要在使用submit时,必须使用一个<form>标签,任意的标签都可以,例如div或者是tr。例如:
< div  id ="fakeForm" > 
   < input  type ="text"  name ="foo"  value ="bar"  /> 
</div> 
<%= link_to_remote "Submit fake form", 
       :submit   => "fakeForm", 
       :url      => { :action => 'repeat' }, 
       :complete => "alert(request.responseText)" %> 
点击这个链接后,会扫描fakeForm DIV并且把里面的数据连带Request,通过HTTP POST发送到repeater这个action,模拟一个规则的表单提交,虽然这个过程没有<form>标签存在于页面上。这个模拟表单提交的功能在不允许嵌套表单时非常有用,使用:submit选项,你可以很轻易的在这种限制下工作。
 
当然,:submit选项对于表单来说也是非常有用的,当你用多种方式提交的时候。例如:
< form  id ="myForm" > 
   < input  type ="text"  name ="text_to_reverse"  id ="text_to_reverse"  /> 
  <%= link_to_remote "Reverse field", 
       :url      => { :action => 'reverse' }, 
       :submit   => "myForm", 
       :complete => "$('text_to_reverse').value=request.responseText" %> 
   < input  type ="submit"  /> 
</form>
这里我们有一个规则的,没有Ajax的表单,但是"Reverse field"这个链接使用了Ajax在幕后提交表单并且利用回应改变表单中的值。
 
:with选项用来构建查询字段,跟request一起发送,在服务器端变成params对象。例如:
<%= link_to_remote "Link with params", 
       :url      => { :action => 'repeat' }, 
       :complete => "alert(request.responseText)", 
       :with     => "'foo=bar'" %>
注意这里,:with的值有两个引号。这是因为它是作为Javascript表达式来执行的,这个case中,我们希望提供一个字符串表达式。这是helper的输出:
<a href="#" 
  new Ajax.Request('/chapter3/repeat', 
    { parameters:'foo=bar', 
      onComplete:function(request){ 
        alert(request.responseText) 
      } 
    }); return false;">Link with params </a>
在:with选项中你也可以使用Javascript变量或者DOM元素:
<input id= "myElement" type= "text" value= "bar" /> 
<%= link_to_remote  "Link with dynamic params"
       :url      => { :action => 'repeat' }, 
       :complete =>  "alert(request.responseText)"
       : with     =>  "'foo='+escape($F('myElement'))" %>
在这个示例中,点击链接会将当前在myElement中的值发送出去。
 
3.2.2.1 Link  to an arbitrary function
我们来看看link_to_remote的大哥哥link_to_function. 它的功能是生成一个执行某个Javascript功能块的链接。在index.rhtml中加入下面的代码:
<%= link_to_function  "Toggle DIV""$('indicator').toggle(  )" %></p>
第一个参数是链接显示的文字,第二个是要执行的Javascript代码块的名字。现在这个代码块使用了Prototype的toggle()方法,这个方法实现隐藏或显示页面上的元素。它控制着我们以前创建的indicator 这个DIV标签内容。这个link_to_function的HTML是这样:
< a  href ="#"  onclick ="$('indicator').toggle(  ); return false;" >Toggle DIV </a> 




本文转自 fsjoy1983 51CTO博客,原文链接:http://blog.51cto.com/fsjoy/91222,如需转载请自行联系原作者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值