2013-05-02 26 views
31

Ho un controller che risponde sia a html sia a js. La vista html esegue il rendering dell'intera pagina (inclusi l'intestazione e il piè di pagina), mentre lo js sostituisce solo #main. A parte l'intestazione e il piè di pagina, entrambi i formati rendono lo stesso contenuto. Posso ottenere questo effetto con tre file:Rails: rendering di una vista (non parziale) da una vista

_show.html.erb 
<div>Content!</div> 

show.html.erb 
<%= render "show" %> 

show.js.erb 
$("#main").fadeIn("<%= escape_javascript(render 'show') %>"); 

Questo funziona, ma preferirei se non ho bisogno di un separato _show parziale. Purtroppo, questo non funziona:

show.html.erb 
<div>Content!</div> 

show.js.erb 
$("#main").fadeIn("<%= escape_javascript(render 'show') %>"); 

come rotaie cercherà il show parziali, non la vista reale.

C'è un modo per ottenere Rails per cercare il file di visualizzazione, piuttosto che parziale?

+3

è possibile utilizzare il': f l'opzione 'ile', ad es. ': file => 'mostra''.L'helper render renderà implicitamente l'argomento stringa di render 'yourview'' in 'render: partial =>' yourview''. Il problema che si sta per affrontare, comunque, è che il contesto di ricerca nell'azione js risolverà "show" nella versione js, probabilmente risultando in un ciclo infinito o qualcosa del genere. – numbers1311407

+0

Per fortuna, non loop. Almeno non ancora. Per ora ricevo un errore 'template mancante'. Sembra che non possa nemmeno trovarsi. – nullnullnull

+1

Il rendering di una vista non parziale all'interno di un'altra vista non è esattamente il Rails Way ™. La tua soluzione attuale è probabilmente migliore. Rinominalo '_body' se ti senti strano riguardo al nome. La cosa comune che vedrai in questo scenario è 'render (@resource)', che si trasforma nel percorso parziale, ad es. 'Risorse/_resource'. – numbers1311407

risposta

23

Il rendering di una vista non parziale all'interno di un'altra vista non è esattamente il Rails Way ™. La tua soluzione attuale è probabilmente migliore e non un approccio insolito. Rinominalo _body, o qualcos'altro appropriato, se ti senti strano riguardo al fatto che il nome parziale sia lo stesso dell'azione.

Tuttavia, se la tua vista può essere condivisa, come sembra che potrebbe in questo caso, potresti semplicemente renderla un layout.

Ciò è facilitato dal fatto che, un po 'contro il principio di minima sorpresa, Rails renderà un modello html per un'azione js se non esiste un modello js. Ciò significa che è possibile rimuovere sia il modello js, ​​e parziale, e solo creare un layout diritto, per esempio, fadein.js.erb:

# yourviews/show.html.erb 
<div>Content!</div> 

# layouts/fadein.js.erb 
$("#main").fadeIn("<%= escape_javascript(yield) %>"); 

# YourController.rb 
def show 
    # ... 
    respond_to do |wants| 
    wants.html 
    wants.js { render :layout => "fadein" } 
    end 
end 
+3

Grazie mille. Questa soluzione riporta tre file ('show.html.erb',' show.js.erb' e '_show.html.erb') in uno' show.html.erb'. Posso applicarlo a modelli e azioni, e ci sarà ancora solo bisogno di un file 'layouts/fadein.js.erb'. Brillante! – nullnullnull

+0

Questo ha funzionato davvero bene! Grazie mille. Ho appena avuto una domanda, non sono riuscito a far funzionare tutto questo per uno scenario "crea" in cui l'invio di un modulo dovrebbe reindirizzare il record che ho appena creato. Ho aggiunto il telecomando: true nel mio form_for, ma cerca il modello di creazione anche se ho risposto a _di fare in modo che JS punti al file JS di layout. Qualche consiglio? Grazie. – Kopty

+0

@Kopty Sta ancora eseguendo il rendering del template, come HTML, all'interno del layout javascript. Quindi cercherà sempre un modello di creazione come al solito, a meno che tu non lo dica. Se si desidera rendere il modello dello spettacolo, si potrebbe fare qualcosa come 'render: show,: layout =>" fadein "' – numbers1311407

9

Questa non è una buona pratica, come potete vedere dai commenti. Rotaie hanno i concetti di vista, parziale e layout. Detto questo, la vista è l'unica che dovresti continuare a usare una sola volta. Così i miei suggerimenti sono:

  1. Se ritieni che più di una vista in più potrebbe essere reso all'interno della vostra vista corrente, è più probabile alla ricerca di un layout
  2. Se si ritiene che uno dei vostri punti di vista dovrebbe essere reso in molte pagine, siete alla ricerca di un parziale
  3. Se questo punto di vista dovrebbe rendere solo una vista in più al suo interno, e che vista dovrebbe essere reso solo all'interno della vista corrente, è possibile scegliere una di queste o niente di tutto questo - questo è tutto, vai con un singolo file
13

Come altri hanno già detto, rendendo un'altra vista non parziale, in un altro punto di vista è " non è il modo in cui le rotaie", se invece ancora insistere a farlo, un metodo è:

<%= render :file => '<replace with relative/absolute path>' %> 
1

si solo bisogno di passare un contesto per il vostro render metodo:

<%= render :template => "show" -%> 
Problemi correlati