Rails 4 esegue il rendering parziale con ajax, jquery,: remote => true e respond_to

Sembra che il rendering di una pagina dynamicmente con AJAX in risposta a un modulo inviato sia comune. Nessuna delle altre domande simili è incentrata su come farlo in generale.

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

La domanda: come faccio a codificare la mia applicazione di rotaie in modo che possa triggersre una vista parziale da caricare tramite AJAX quando invio un modulo o faccio clic su un collegamento?

Diverse cose devono essere presenti affinché funzioni, tra cui: remote => true flag sull’elemento di trigger, respond_to: js flag nella definizione della class del controller, il route, la vista parziale e infine il jquery per il rendering effettivo di una dynamic partial deve essere contenuto in un file .html.js separato.

Gli esempi che seguono sono per un metodo fittizio “render_partial_form” del controller “someajax”.

1) Aggiungi a: remote => true flag all’elemento di triggerszione
metti il: remote => true flag sul link o form tag nel tuo file .html.erb (view) per l’elemento che vuoi triggersre la chiamata AJAX, come

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

con: remote => true, rails non cambierà automaticamente le visualizzazioni, il che consente invece di eseguire JQuery. Può essere utilizzato con un tag form, un tag link o altri tipi di tag.

2) Aggiungi “answer_to: html,: js” nella parte superiore del controller

Nella parte superiore della definizione della class del controller, è necessario specificare che il controller può rispondere a javascript e ad html:

 class SomeajaxController < ApplicationController respond_to :html, :js ... def render_partial_form @array_from_controller = Array.new ... end end 

In questo esempio, una variabile viene passata dal controller alla vista: una serie di opzioni di elenco selezionate chiamate @array_from_controller .

3) Instradare il verbo http al metodo del controller

Dal momento che volevo un form POST per triggersre la chiamata AJAX, ho indirizzato il verbo post del mio controller alla vista render_partial_form.

 post 'someajax' => 'someajax#render_partial_form 

Il metodo controller definito da def render_partial_form corrisponde al nome della vista, _render_partial_form.html.erb , quindi non è necessario richiamare un'azione di rendering dal controller.

4) Crea la vista parziale
La vista parziale dovrebbe avere lo stesso nome del metodo del controller e iniziare con un carattere di sottolineatura: _render_partial_form.html.erb

 

Here is the partial form

<%= 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 triggersno 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". Crea un file con estensione .js.erb e lo stesso nome del tuo controller:

render_partial_form.js.erb

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

Dovresti usare le viste JS (che hanno l’estensione “js.erb”), qualcosa come “create.js.erb” per creare un’azione del controller. Quindi, aggiungi format.js a respond_to do |format| ... end respond_to do |format| ... end blocco respond_to do |format| ... end . E aggiungi remoto: vero parametro al tuo modulo. Avviso: js.erb dovrebbe includere il codice Javascript che devi includere, come:

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

Per quello che vale (perché stavo intervenendo su questo in un aggiornamento dell’app da Rails 2 a 3): puoi farlo anche aggiungendo un gestore di eventi che aggiunge l’HTML restituito, come la vecchia libreria di prototipi Rails 2 usata per fare.

Se, ad esempio, stai cercando di prenderlo (preparati per una frase runon):

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

Dove la risposta arriva come HTML e viene aggiunta automaticamente e la sostituisce con questa:

 form_tag {...}, remote: true 

Aggiungendo un gestore di eventi al file application.js che fa semplicemente la stessa cosa, aggiungendo il contenuto a un elemento specifico, come questo:

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

Allora … potresti incontrare lo stesso problema che ho avuto, ovvero che non spara mai l’ ajax:success evento di 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!