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

Posted

技术标签:

【中文标题】rails3 rails.js 和 jquery 捕获 ajax 请求的成功和失败【英文标题】:rails3 rails.js and jquery catching success and failure of ajax requests 【发布时间】:2011-03-30 21:38:45 【问题描述】:

以前,在 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" 

(来自documentation 的示例)。 此示例将在成功时使用类“cart”更新 html 元素,并在失败时使用类“error”。

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

link_to "Add to cart", :url => :action => "add", :id => product.id, 
    :remote => true

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

$('.cart').replaceWith(<%= escape_javascript(render :partial => 'cart') %>)

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

以某种方式能够模仿我们以前的行为对我来说似乎很有用。有什么想法吗?

【问题讨论】:

【参考方案1】:

哈!我发现它在this 文章中有所描述。在 rails.js 中检查了以下回调:

ajax:loading : 在执行 AJAX 请求之前触发 ajax:success : AJAX 请求成功后触发 ajax:complete : 在 AJAX 请求完成后触发,与响应状态无关 ajax:failure : 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()" %>

翻译成这样:

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

在一些 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);
    );
);

太棒了! :)

[更新:2011 年 12 月 29 日]

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

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);
    );

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

 .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) )

【讨论】:

只有我认为他们在从 Rails 中删除简单的 javascript 方面后退了一步吗? 就像 css 将大部分布局与内容 (HTML) 分开一样,最好将行为与 HTML 分开(所以使用不显眼的 js)。虽然这确实更难(起初),但它也使您的 HTML/JS 更易于阅读(明智地使用您的类名和标识符),并使您的 JS 更易于维护和长期重用。跨度> 'ajax:loading' 对我不起作用,我不得不使用 'ajax:before' - 以防万一其他人遇到这个问题。 (轨道 3.1.1) @Axsuul:请检查rails.js的代码:没有触发事件变量! 有关最新的 jQuery rails 回调,请参见 GitHub 页面:github.com/rails/jquery-ujs/wiki/ajax【参考方案2】:

相关的 rails 4 指南可以在以下位置找到:http://guides.rubyonrails.org/working_with_javascript_in_rails.html

它指向事件的文档:https://github.com/rails/jquery-ujs/wiki/ajax,如 ncherro 所述

传递给回调的实际值可以从jQuery的ajax方法http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings推断出来

.bind 被 jQuery 弃用,取而代之的是 .on:http://api.jquery.com/on/

所以现在推荐的方法是:

模板:

<%= link_to 'Click me!',
    'path/to/ajax',
    remote: true,
    id: 'button',
    method: :get,
    data: type: 'text'
%>

咖啡脚本:

$(document).ready ->
  $("#button").on("ajax:success", (e, data, status, xhr) ->
    alert xhr.responseText
  ).on "ajax:error", (e, xhr, status, error) ->
    alert "error"

【讨论】:

【参考方案3】:

我知道这个问题已经存在 3 年了,但它在 Google 搜索结果中的排名很高,并且上面列出的一些事件不再使用。

在此处查看当前列表 - https://github.com/rails/jquery-ujs/wiki/ajax

【讨论】:

以上是关于rails3 rails.js 和 jquery 捕获 ajax 请求的成功和失败的主要内容,如果未能解决你的问题,请参考以下文章

Rails '.js.erb' 不呈现部分

Rails3/jQuery UI Datepicker - 月份和日期在保存时反转

通过 rails3-jquery-autocomplete 使用多个输入字段

如果没有可用数据,rails3-jquery-autocomplete 清除字段

rails3中的jquery tokeninput javascript

Rails 3.1 和 jquery-ui 资产