web-dev-qa-db-ja.com

rails3Rails.jsとjqueryがajaxリクエストの成功と失敗をキャッチ

以前は、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" }

ドキュメント からの例)。この例では、成功するとクラス「cart」でhtml要素を更新し、失敗するとクラス「error」を更新します。

今、私は手口が変わったと信じています、代わりに私たちはこう書きます:

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

:updateを設定するオプションはもうありません。通常のhtmlの代わりに、次のようにjavascriptをレンダリングします(jqueryで):

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

しかし、エラー状況をどのように処理しますか?コントローラで処理し、別のビューを使用しますか?

どういうわけか、以前の動作を模倣できると便利だと思います。何か案は?

25
nathanvda

ハ! this の記事で説明されていることがわかりました。 Rails.jsでは、次のコールバックがチェックされます。

  • ajax:loading:AJAXリクエストを実行する前にトリガーされます
  • ajax:success:成功したAJAXリクエストの後にトリガーされます
  • ajax:complete:応答のステータスに関係なく、AJAXリクエストが完了した後にトリガーされます
  • ajax:failure:ajax:successとは対照的に、失敗したAJAXリクエストの後にトリガーされます

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日]

最近、2つのイベントの名前が変更されました。

  • ajax:beforeSend:後期のajax:loadingを置き換えます
  • ajax:errorajax: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) {})
71
nathanvda

関連するRails 4ガイドは次の場所にあります: http://guides.rubyonrails.org/working_with_javascript_in_Rails.html

これは、次のイベントのドキュメントを指します: https://github.com/Rails/jquery-ujs/wiki/ajax 、ncherroが言及しているように

コールバックに渡される実際の値は、j​​Queryのajaxメソッドから推測できます http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings

.bindは廃止されて.on by 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年前のものですが、Googleの検索結果で上位に表示され、上記のイベントの一部は使用されなくなりました。

現在のリストについては、こちらをご覧ください https://github.com/Rails/jquery-ujs/wiki/ajax

1
ncherro