2010-08-17 12 views
25

Zuvor, in Schienen 2.3.8 habe ich die Prototyp-Helfer link_to_remote und form_remote_for (unter anderem) verwendet.rails3 rails.js und jquery fangen Erfolg und Misserfolg von AJAX-Anfragen

Diese hatten die Möglichkeit, :update wie folgt:

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

(ein Beispiel aus dem documentation). Dieses Beispiel würde bei Erfolg das html-Element mit der Klasse "cart" und bei einem Fehler die Klasse "error" aktualisieren.

Jetzt glaube ich die Vorgehensweise geändert hat, sondern wir schreiben:

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

und es gibt keine Option :update mehr einzustellen. Statt eines normalen html, machen wir jetzt JavaScript aktivieren, wie folgt aus (in jquery):

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

aber, wie Sie eine Fehlersituation gehe? Behandle ich es in meinem Controller und verwende separate Ansichten?

Es scheint mir nützlich zu sein, irgendwie das Verhalten nachzuahmen, das wir vorher hatten. Irgendwelche Ideen?

Antwort

71

Ha! Ich fand es beschrieben in this Artikel. In rails.js folgende Rückrufe geprüft werden:

  • Ajax: Laden: ausgelöst, bevor der AJAX-Request
  • Ajax-Ausführung: success: ausgelöst nach einer erfolgreichen AJAX-Request
  • Ajax: alle: ausgelöst, nachdem der AJAX Anfrage abgeschlossen ist, unabhängig von dem Status der Antwort
  • ajax: failure: ausgelöst nach gescheitertem aJAX-Request, wie gegenüber ajax: Erfolg

wie die Javascript unaufdringlich sein sollte, Diese Kopplung wird nicht im HTML durchgeführt.

Ein Beispiel (aus dem gleichen Ort): Die folgende Rails 2.3.8

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

wird dies übersetzt:

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

und innerhalb einiger Javascript (application.js) Sie binden die ereignisse

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

Großartig!:)

[UPDATE: 29.12.2011]

Zwei Ereignisse wurden in letzter Zeit umbenannt:

  • ajax:beforeSend: ersetzen die späte ajax:loading
  • ajax:error ersetzt die ajax:failure (ich glaube zu sein mehr im Einklang mit jQuery selbst)

So würde mein Beispiel werden:

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

Für Vollständigkeit, die Ereignisse und ihre erwarteten Parameter:

.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) {}) 
+6

Bin ich der einzige, der sie denkt, einen Schritt zurück mit dem Entfernen von einfachem Javascript von Rails? – Amala

+6

Wie css einen Großteil des Layouts vom Inhalt (HTML) trennt, ist es auch besser, das Verhalten von HTML zu trennen (also unauffällige js zu verwenden). Obwohl dies in der Tat schwieriger ist (zuerst), macht es auch Ihren HTML/JS leichter lesbar (verwenden Sie Ihre Klassennamen und Identifikatoren mit Bedacht), und macht Ihre JS einfacher zu pflegen und im weiteren Verlauf wiederzuverwenden. – nathanvda

+1

'ajax: loading' funktionierte nicht für mich, ich musste 'ajax: before' verwenden - nur für den Fall, dass jemand anderes auf dieses Problem trifft. (Rails 3.1.1) – tmaximini

4

Die zugehörigen Schienen 4 Leitfaden kann unter: http://guides.rubyonrails.org/working_with_javascript_in_rails.html

Er verweist auf die Dokumentation der Ereignisse an: https://github.com/rails/jquery-ujs/wiki/ajax, wie ncherro erwähnt

Die tatsächlichen Werte an die Rückrufe geben können von jQuery ajax Methode http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings

.bind geschlossen werden für .on von jQuery ist veraltet: http://api.jquery.com/on/

So, jetzt die empfohlene Vorgehensweise ist:

Vorlage:

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

Coffeescript:

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