2009-09-30 20 views
5

Sto provando a scrivere un metodo di controller Rails che risponderà per ottenere richieste effettuate sia "normalmente" (ad esempio seguendo un collegamento) che tramite ajax.Come rispondere alle richieste HTML effettuate tramite AJAX in Rails

Caso normale: il controller deve rispondere con HTML completamente decorato utilizzando il layout.

Caso Ajax: Il conroller dovrebbe rispondere con il Frammento HTML generato dal modello (senza layout)

Ecco il codice jQuery, ho creato per l'esecuzione sul lato client per fare la richiesta GET.

jQuery.get("http://mydomain.com/some_controller/some_action", 
      {}, 
      function(data, textstatus) { 
      jQuery("#target").html(data); 
      }, 
      "html"); 

Qual è il modo migliore per gestire questo in Rails?

risposta

13

Nel controller selezionare dinamicamente se utilizzare un layout basato su request.xhr?.

Ad esempio:

class SomeController < ApplicationController 
    layout :get_layout 

    protected 

    def get_layout 
    request.xhr? ? nil : 'normal_layout' 
    end 
end 
9

nel metodo di controllo, è sufficiente fare questo:

respond_to do |format| 
     format.js if request.xhr? 
     format.html { redirect_to :action => "index"} 
    end 
+0

Ooh - Non sapevo della richiesta.XHR? Spero non ti dispiaccia se modifico la mia risposta per usarlo. – DanSingerman

+2

Nel contesto della domanda, 'format.js' non è l'opzione migliore dal momento che ne vuole l'html. E per farlo funzionare il tuo template js dovrebbe generare html, che è fonte di confusione. – artemave

0

Se si utilizza una nuova versione di rotaie si può solo aggiungere .js sul percorso e si dedurrà che la richiesta è una chiamata JavaScript

3

Un altro modo per farlo sarebbe quello di registrare il nuovo formato e specify it explicitly in url.

mettere questo in config/initializers/mime_types.rb:

Mime::Type.register_alias 'text/html', :xhtml 

Salvare il modello nella some_controller/some_action.xhml.haml.

E aggiungere formato url: http://mydomain.com/some_controller/some_action.xhtml, o, meglio, utilizzare

url_for(:controller => :some_controller, :action => :some_action, :format => :xhtml) 

o, meglio ancora, aiutanti di percorso (se siete abbastanza riposante):

some_controller_some_action_imaginary_path(:format => :xhtml) 

Mente, che non è richiesto il dispacciamento esplicito di respond_to perché funzioni.

Questa tecnica potrebbe essere eccessiva se tutto ciò che si desidera è il layout di commutazione per lo stesso modello, ma se le versioni normale e ajax sono diverse, allora è sicuramente un modo per andare.


EDIT:
Il jQuery 1.5.1 appena rilasciato porta l'opzione per specificare tipo MIME in $.ajax():

mimeType: un tipo MIME per ignorare il tipo MIME XHR.

Questa potrebbe essere un'alternativa al formato esplicito in URL, anche se non l'ho ancora provato.

+0

Questa è una grande soluzione discreta. Tuttavia, invece di modificare l'URL, mi piace usare semplicemente: 'answer_to: xhtml se request.xhr?' nel controller. –

Problemi correlati