2013-09-03 20 views
17

Voglio caricare file con AJAX. In passato ho realizzato questo utilizzando il magico jQuery form plugin e ha funzionato alla grande. Attualmente sto costruendo un'app Rails e sto provando a fare cose "The Rails Way", quindi sto utilizzando Form Helper e la gemma paperclip per aggiungere file allegati.Rails 4: Come caricare file con AJAX

Il rails docs avvertono che il Helper Form non funziona per il caricamento di file AJAX:

differenza di altre forme che effettuano una form di upload asincrono non è così semplice come fornire form_for con telecomando: vero. Con un modulo Ajax la serializzazione viene eseguita da JavaScript in esecuzione nel browser e poiché JavaScript non può leggere i file dal disco rigido del file non può essere caricato. La soluzione più comune è utilizzare un iframe invisibile che funge da destinazione per l'invio del modulo.

Sembra chiaro che non esiste una soluzione pronta per l'acquisto. Quindi mi chiedo quale sia la cosa più intelligente da fare. Sembra che io abbia diverse opzioni:

  1. Usa l'helper del modulo e il trucco dell'iframe.
  2. la compilazione del modulo helper + carico jQuery modulo plugin per inviare il file (non so se questo sarà bello giocare con l'autenticità di Rails gettone, ecc)
  3. Utilizza il modulo helper + graffetta + [qualche altra gemma] per estendere sue funzionalità per consentire l'invio del modulo AJAX.

Tutti e tre sembrano possibili. Conosco il n. 3, in particolare la parte [di qualche altra gemma]. Ho trovato due domande simili (this e this) che menzionano un ramo di Pic-Upload chiamato Uploadify ma che hanno entrambi 2 anni e si occupano di Rails 2 e 3 (e Uploadify non è stato aggiornato da anni). Quindi, visto quanto è cambiato, credo che questo è davvero tutta una questione nuova:

Qual è il modo migliore per caricare i file con l'Ajax in Rails 4?

+0

Penso che la citazione spieghi chiaramente il motivo per cui l'hai sempre fatto "usando il magico plug-in di modulo jQuery";) –

+0

Qualche consiglio sul modo più semplice di utilizzarlo insieme al modulo di aiuto di Rails? Sto pensando che NON dovrei usare il: remote => true e lasciare che il plugin del modulo faccia il lavoro. – emersonthis

+0

Questo plugin è fantastico - l'ho provato e funziona come un incantesimo. Grazie per la domanda informativa :) – Jay

risposta

7

Dai un'occhiata alla gemma remotipart: https://github.com/JangoSteve/remotipart - potresti farti arrivare fin lì con pochissimo lavoro!

+3

Un sacco di problemi aperti, ero particolarmente spaventato da quelli riguardanti la compatibilità con rails 4 – Jay

+0

remotipart funziona bene con le guide 4 – KenB

+0

Ho usato remotipart con le guide 4, l'immagine è stata caricata, ma l'aggiornamento della risposta. js.erb non viene eseguito. Aiuto PLz – Santanu

1

IMHO Rails non è perfetto quando si tratta di caricare file utilizzando AJAX, soprattutto se si desidera una barra di avanzamento. Il mio suggerimento è di usare Javascript per l'invio del modulo su una richiesta AJAX come suggerito in (2). Se hai dimestichezza con Javascript non avrai molti problemi.

Recentemente ho usato lo stesso approccio utilizzando questo molto semplice libreria JS https://github.com/hayageek/jquery-upload-file e ho scritto maggiori dettagli qui http://www.alfredo.motta.name/upload-video-files-with-rails-paperclip-and-jquery-upload-file/

Per un'applicazione con un modulo per caricare un film con il titolo e la descrizione del codice JS si presenta come segue:

$(document).ready(function() { 
    var uploadObj = $("#movie_video").uploadFile({ 
    url: "/movies", 
    multiple: false, 
    fileName: "movie[video]", 
    autoSubmit: false, 
    formData: { 
     "movie[title]": $('#movie_title').text(), 
     "movie[description]": $('#movie_description').text() 
    }, 
    onSuccess:function(files,data,xhr) 
    { 
     window.location.href = data.to; 
    } 
    }); 

    $("#fileUpload").click(function(e) { 
    e.preventDefault(); 
    $.rails.disableFormElements($($.rails.formSubmitSelector)); 
    uploadObj.startUpload(); 
    }); 
}); 

Lontano da perfetto, ma offre flessibilità sul frontend.

Problemi correlati