rails3 rails.js和jquery捕获ajax请求的成功和失败

nat*_*vda 25 ajax jquery ruby-on-rails ruby-on-rails-3

以前,在rails 2.3.8中我使用了原型助手link_to_remoteform_remote_for(其中包括).

这些选项:update如下:

link_to_remote "Add to cart",
  :url => { :action => "add", :id => product.id },
  :update => { :success => "cart", :failure => "error" }
Run Code Online (Sandbox Code Playgroud)

(文档中的一个例子).这个例子在成功更新带有"cart"类的html元素时,失败后会出现类"错误".

现在我相信作案手法已经改变了,而是我们写道:

link_to "Add to cart", :url => {:action => "add", :id => product.id}, 
    :remote => true
Run Code Online (Sandbox Code Playgroud)

并且没有选项可以再设置:update了.而不是普通的html,我们现在渲染javascript,就像这样(在jquery中):

$('.cart').replaceWith(<%= escape_javascript(render :partial => 'cart') %>)
Run Code Online (Sandbox Code Playgroud)

但是你如何处理错误情况呢?我是否在控制器中处理它,并使用单独的视图?

以某种方式能够模仿我们之前的行为似乎对我有用.有任何想法吗?

nat*_*vda 71

哈!我发现它在描述这个文章.在rails.js中,检查以下回调:

  • ajax:loading:在执行AJAX请求之前触发
  • ajax:success:成功的AJAX请求后触发
  • ajax:complete:在AJAX请求完成后触发,无论响应的状态如何
  • ajax:失败:在AJAX请求失败后触发,与ajax相反:success

因为javascript应该是不显眼的,所以这种耦合不是在HTML中完成的.

一个例子(来自同一站点):以下Rails 2.3.8

<% form_remote_tag :url => { :action => 'run' },
        :id => "tool-form",
        :update => { :success => "response", :failure => "error" },
        :loading => "$('#loading').toggle()", :complete => "$('#loading').toggle()" %>
Run Code Online (Sandbox Code Playgroud)

被翻译成这个:

<% form_tag url_for(:action => "run"), :id => "tool-form", :remote => true do %>
Run Code Online (Sandbox Code Playgroud)

在一些javascript(application.js)中,你绑定事件

jQuery(function($) {
  // create a convenient toggleLoading function
  var toggleLoading = function() { $("#loading").toggle() };

  $("#tool-form")
    .bind("ajax:loading",  toggleLoading)
    .bind("ajax:complete", toggleLoading)
    .bind("ajax:success", function(xhr, data, status) {
      $("#response").html(status);
    });
});
Run Code Online (Sandbox Code Playgroud)

大!:)

[更新日期:29/12/2011]

最近有两个事件被重命名:

  • ajax:beforeSend:更换晚了 ajax:loading
  • ajax:error替换ajax:failure(我想更符合jQuery本身)

所以我的例子将成为:

  $("#tool-form")
    .bind("ajax:beforeSend",  toggleLoading)
    .bind("ajax:complete", toggleLoading)
    .bind("ajax:success", function(xhr, data, status) {
      $("#response").html(status);
    });
Run Code Online (Sandbox Code Playgroud)

为了完整性,事件及其预期参数:

 .bind('ajax:beforeSend', function(xhr, settings) {})
 .bind('ajax:success',    function(xhr, data, status) {})
 .bind('ajax:complete', function(xhr, status) {})
 .bind('ajax:error', function(xhr, data, status) {})
Run Code Online (Sandbox Code Playgroud)

  • 我是唯一一个认为他们从Rails中删除简单的javascript后退了一步的人吗? (6认同)
  • 就像css从内容(HTML)中拆分大部分布局一样,从HTML中分离行为也更好(所以使用不引人注目的js).虽然这确实更难(首先),但它也使您的HTML/JS更易于阅读(明智地使用您的类名和标识符),并使您的JS更易于在longrun中维护和重用. (6认同)
  • 对于最新的jQuery rails回调,请参阅GitHub页面:https://github.com/rails/jquery-ujs/wiki/ajax (3认同)