2014-11-07 18 views
24

Sembra che il rendering di una pagina dinamicamente con AJAX in risposta a un modulo inviato sia comune. Nessuna delle altre domande simili è incentrata su come farlo in generale.Rails 4 esegue il rendering parziale con ajax, jquery,: remote => true e risponde_a

Il miglior post sul blog che ho trovato su questo argomento è stato qui: http://www.gotealeaf.com/blog/the-detailed-guide-on-how-ajax-works-with-ruby-on-rails

La domanda: Come faccio a codifico mia applicazione rotaie in modo che possa innescare una vista parziale di caricare tramite la tecnologia AJAX quando invio un form o fare clic su un collegamento?

risposta

32

Molte cose devono essere presenti per far funzionare tutto questo, compreso il: ritirato => vera bandiera sull'elemento scatenante, il respond_to : js flag nella definizione della classe del controller, il percorso, la vista parziale e infine il jquery per il rendering effettivo di un partial dinamico deve essere contenuto in un file .html.js separato.

Gli esempi di seguito sono per un metodo fittizio "render_partial_form" del controller "someajax".


1) Aggiungere un: a distanza => vera bandiera con l'elemento scatenante
mettere il: distanza => vera bandiera sul tag link o modulo nel file .html.erb (vista) per il elemento che si desidera attivare la chiamata AJAX, come

<%= form_tag("/someajax", method: 'post', :remote => true) do %> 

con: a distanza => true, rotaie non passa automaticamente di vista, che permette al JQuery da eseguire, invece. Può essere utilizzato con un tag form, un tag link o altri tipi di tag.


2) Aggiungere "respond_to: html,: js" nella parte superiore del controller

Nella parte superiore della definizione di classe del controller, è necessario ora specificare che il controller in grado di rispondere a JavaScript come pure come html:

class SomeajaxController < ApplicationController 
    respond_to :html, :js 

    ... 

    def render_partial_form 
     @array_from_controller = Array.new 

     ... 

    end 
end 

In questo esempio, c'è un essere variabile passata dal controller nella vista: un array di selezionare le opzioni di elenco chiamati @array_from_controller.


3) Far passare il http verbo metodo del controller

dato che volevo una forma Pubblicato per attivare la chiamata AJAX, ho indirizzato il palo verbo per il mio controller alla vista render_partial_form.

post 'someajax' => 'someajax#render_partial_form 

Procedimento controllore definito da def render_partial_form corrispondenze con il nome della vista, _render_partial_form.html.erb quindi non c'è bisogno di chiamare un rendering azione dal controller.


4) Creare la vista parziale
La vista parziale deve avere lo stesso nome come metodo di controllo e iniziare con un carattere di sottolineatura: _render_partial_form.html.erb

<h3>Here is the partial form</h3> 

<%= form_tag("/next_step", method: 'post') do %> 
    <%= label_tag(:data, "Some options: ") %> 
    <%= select_tag(:data, options_for_select(@array_from_controller.transpose[0].collect)) %> 
    <%= submit_tag('Next') %> 
<% end %> 


5) Creare il file JQuery

Le istruzioni JQuery attivano il rendering del modulo. Sostituisci "render_partial_form" con il nome effettivo del tuo metodo di controllo e vista parziale. L'effetto slideDown è opzionale "eye candy". Creare un file con estensione .js.erb, e lo stesso nome del vostro controller:

render_partial_form.js.erb

$('#render_partial_form').html("<%= escape_javascript (render partial: 'render_partial_form') %>"); 
$('#render_partial_form').slideDown(350); 
+2

Nelle versioni di Rails più recenti è necessario il gem di "responders" per implementare il livello di controllo answer_to: html,: js – emery

+1

Il fatto che il partial abbia dovuto essere denominato uguale al metodo AJAX è ciò che mi ha salvato. Spero che altri possano trovare questo, ottima risposta. – justinraczak

+0

Grazie. In realtà ho avuto qualche problema nel far funzionare più a fondo questo aspetto su un progetto diverso ... Mi chiedo se i dati: {type:: html} dovessero essere nel form_tag, come per la risposta di mltsy. – emery

10

Dovresti usare le viste JS (che hanno estensione "js.erb"), qualcosa come "create.js.erb" per creare un'azione del controller. Quindi, aggiungere format.js al blocco respond_to do |format| ... end. E aggiungi remoto: vero parametro al tuo modulo. Avviso: js.erb dovrebbe includere codice Javascript è necessario per essere inclusi, come:

$("tbody#items").append("<%= j render(partial: 'your_partial_path') %>") 
2

Per quel che vale (perché ero inciampare su questo in un app aggiornamento da Rails 2 a 3): puoi farlo anche aggiungendo un gestore di eventi che accoda l'HTML restituito, come la vecchia libreria di prototipi Rails 2 usata per fare.

Se, per esempio, si sta cercando di prendere questo (preparare una frase RunOn):

form_remote_tag url: {...}, update: ... 

Se la risposta è in arrivo in formato HTML e di essere aggiunto automaticamente, e sostituirlo con questo:

form_tag {...}, remote: true 

Con l'aggiunta di un gestore di eventi al file application.js che fa semplicemente la stessa cosa, aggiungendo il contenuto di uno specifico elemento, in questo modo:

$("#myform").on('ajax:success', function(e, data, status, xhr) { 
    $("#container").append(data); 
)}; 

Quindi ... si può incontrare lo stesso problema che ho fatto, che è che non si accende mai l'evento ajax:success! Il problema è che si aspetta JS o il testo nella risposta, ma sta ricevendo l'HTML. Il modo per risolvere questo è dire che la risposta sarà HTML usando un attributo sul tag form:

form_tag {...}, remote: true, data: {type: :html} 

Pezzo di torta!