rails3 rails.js and jquery catching success and fa

2019-01-13 04:13发布

问题:

Previously, in rails 2.3.8 i used the prototype-helpers link_to_remote and form_remote_for (amongst others).

These had the option :update as follows:

link_to_remote "Add to cart",
  :url => { :action => "add", :id => product.id },
  :update => { :success => "cart", :failure => "error" }

(an example from the documentation). This example would, upon success update the html-element with class "cart", and upon failure the class "error".

Now i believe the modus operandi has changed, instead we write:

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

and there is no option to set :update anymore. Instead of a normal html, we now render javascript, like this (in jquery) :

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

but how do you handle an error situation? Do i handle it in my controller, and use seperate views?

It would seem useful to me to somehow be able to mimic the behaviour we had before. Any ideas?

回答1:

Ha! I found it described in this article. In rails.js the following callbacks are checked:

  • ajax:loading : triggered before executing the AJAX request
  • ajax:success : triggered after a successful AJAX request
  • ajax:complete : triggered after the AJAX request is complete, regardless the status of the response
  • ajax:failure : triggered after a failed AJAX request, as opposite to ajax:success

As the javascript should be unobtrusive, this coupling is not done in the HTML.

An example (from the same site) : the following Rails 2.3.8

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

is translated to this :

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

and inside some javascript (application.js), you bind the events

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

Great! :)

[UPDATE: 29/12/2011]

Two events have been renamed lately:

  • ajax:beforeSend: replace the late ajax:loading
  • ajax:error replaces the ajax:failure (I guess to be more in line with jQuery itself)

So my example would become:

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

For completeness, the events and their expected parameters:

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

The related rails 4 guide can be found at: http://guides.rubyonrails.org/working_with_javascript_in_rails.html

It points to the documentation of the events at: https://github.com/rails/jquery-ujs/wiki/ajax , as mentioned by ncherro

The actual values passed to the callbacks can be inferred from jQuery's ajax method http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings

.bind is deprecated in favor of .on by jQuery: http://api.jquery.com/on/

So now the recommended approach is:

Template:

<%= 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:

I know this question is 3 years old, but it comes up high in Google results and some of the events listed above are not used anymore.

See here for a current list - https://github.com/rails/jquery-ujs/wiki/ajax