代码之家  ›  专栏  ›  技术社区  ›  nathanvda

Rails3 rails.js和jquery捕获Ajax请求的成功和失败

  •  25
  • nathanvda  · 技术社区  · 14 年前

    以前,在Rails 2.3.8中,我使用了原型助手 link_to_remote form_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
    

    也没有设置选项 更新 不再。 我们现在呈现的是JavaScript,而不是普通的HTML(在jQuery中):

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

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

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

    3 回复  |  直到 10 年前
        1
  •  71
  •   CafeHey    13 年前

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

    • Ajax:加载:在执行Ajax请求之前触发
    • Ajax:成功:在成功的Ajax请求之后触发
    • Ajax:完成:在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) {})
    
        2
  •  4
  •   Ciro Santilli OurBigBook.com    10 年前

    相关的导轨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 被否决,赞成 .on 通过jQuery: http://api.jquery.com/on/

    所以现在推荐的方法是:

    模板:

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

    CoffeScript:

    $(document).ready ->
      $("#button").on("ajax:success", (e, data, status, xhr) ->
        alert xhr.responseText
      ).on "ajax:error", (e, xhr, status, error) ->
        alert "error"
    
        3
  •  1
  •   ncherro    11 年前

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

    有关当前列表,请参阅此处- https://github.com/rails/jquery-ujs/wiki/ajax