2016-11-01 2 views
0

Ich muss meine Rails-Anwendung einige AJAX/JS-Funktionalität hinzufügen.Rails 4 - Rendern teilweise mit AJAX/JS

Dies ist die Seite arbeite ich an: enter image description here

über den Inhalt des Registerkarte anzuzeigen, ich rufe

<%= render 'tape_bulk_cocs/sporeCounts' %>

Innerhalb dieses Teils ist der folgende Code (abzüglich der hTML-Tags Text anzuzeigen):

<div id="samples"> 
    <% if @tape_bulk_coc.tape_bulk_coc_samples.any? %>  
     <% @tape_bulk_coc.tape_bulk_coc_samples.each do |cur| %> 
      <% if !cur.spore_type_count %> 
      <%= link_to 'Add Spore Count', new_spore_type_count_path(:tape_bulk_coc_sample_id=>cur.id), :remote=>true, :id => "new_spore_count", class: "tiny button expanded" %> 
      <% end %> 
     <% end %> 
    <% end %> 
</div> 

Inside my spore_type_counts_controller/new Ich habe:

def new 
    @spore_type_count = SporeTypeCount.new 
    @tape_bulk_sample_id = params[:tape_bulk_coc_sample_id] 
    @category_count = [["Rare: 1 to 10","Rare: 1 to 10"], ["Low: 11 to 100","Low: 11 to 100"], ["Medium: 101 to 1000","Medium: 101 to 1000"], ["High: > 1000","High: > 1000"]] 

    respond_to do |format| 
     format.js 
    end 
    end 

, dann in app/views/spore_type_counts/new.js.erb

$('#samples').hide().after('<%= j render("spore_type_counts/form") %>');

Bisher funktioniert alles wie vorgesehen, und wenn ich die Registerkarte Änderungen "Spore Count hinzufügen" klicken wie so erscheinen: enter image description here

Hier ist das Problem, das ich habe.

Als ich die einreichen spore_type_counts/form Ich gehe in die create Aktion für die Steuerung, die dies:

def create 
    @spore_type_count = SporeTypeCount.new(spore_type_count_params) 

    respond_to do |format| 
     if @spore_type_count.save 
     format.js { render 'tape_bulk_cocs/sporeCounts'} 
     end 
    end 
    end 

Einmal hier, alles in die Datenbank sendet korrekt, aber die Seite nicht ändert. Ich kann nicht herausfinden, wie man das tape_bulk_cocs/sporeCounts teilweise wieder rendert (erstes Bild).

Im Wesentlichen, sobald ich das Formular absende, muss ich von der zurück zu tape_bulk_coc_controller/show und aktualisieren Sie meine Objekte, ohne die Seite zu aktualisieren.

Wie kann ich das tun? Oder muss ich meine Anwendung anders strukturieren, um anders zu arbeiten?

Antwort

1

Sie müssen das DOM mit dem Inhalt aus dem Teil aktualisieren, ähnlich wie in der Vorlage . Im Moment sagst du nur "render this partially", aber die Seite weiß nicht, wie sie sich mit diesem Inhalt aktualisieren soll, es sei denn, du erzählst es über JavaScript.

Versuchen Sie, eine spore_type_counts/create.js.erb Datei zu erstellen, die ausgeführt wird, nachdem die SporeTypeCounts#create Aktion ausgeführt wurde. Fügen Sie in dieser Vorlage den JavaScript-Code hinzu, der Ihre Seite mit dem Inhalt aktualisiert, den Sie aus dem Teil wiedergeben.

Zum Beispiel

// hide the previous content 
$("#spore-count-form").remove(); 

// show the new content 
$('#samples').html("<%= j render('tape_bulk_cocs/sporeCounts') %>"); 

Ein paar Dinge zu beachten:

  • aktualisieren die oben genannten Selektoren Ihre App passen. Normalerweise verwende ich data-attributes, um etwas zu markieren, das ich mit JavaScript (z. B. data-ujs-target=spore-form) manipulieren werde. Auf diese Weise werden die JS-Interaktionen nicht unterbrochen, wenn jemand versehentlich eine ID oder CSS-Klasse ändert.

  • Möglicherweise müssen Sie Ihr Markup aktualisieren, um es mithilfe von jQuery zu ändern.

  • Wenn tape_bulk_cocs/sporeCounts keine Instanzvariablen verwendet, stellen Sie sicher, dass sie innerhalb dem der SporeTypeCounts#create Aktion definiert sind, sonst wird der Teil nicht machen. (HINWEIS: you really should avoid using instance variables within partials aus diesem Grund)

Hoffnung, das hilft!

+0

Vielen Dank für die Antwort. Ich war ziemlich weit gekommen, bevor ich deine Antwort sah. Ich hatte bereits eine 'spore_type_counts/create.js.erb'-Datei, aber ich hatte Mühe herauszufinden, was ich hineinstecken sollte. Ich hatte etwas, das funktionierte, aber nachdem ich deine Antwort gesehen hatte, habe ich es perfektioniert. Die Lösung kam von dem Hinzufügen des folgenden zu create.js.erb: $ ('# spore_count'). Remove(); $ ('# samples'). Show(). Html ("<% = j render ('tape_bulk_cocs/sporeCounts')%>"); ' –

+0

Gibt es eine Möglichkeit, die anderen Registerkarten gleichzeitig zu aktualisieren ihren Inhalt anzeigen? Speziell meine Registerkarte für die 'Gespeicherten Samples'. Wenn ich einen 'spore_type_count' übergebe, benötige ich das Beispiel innerhalb der' Gespeicherten Beispiele'-Registerkarte, um den spore_count anzuzeigen, ohne die Seite aktualisieren zu müssen. –

+0

Ich bin froh, dass ich helfen konnte! Um Ihre Frage zu aktualisieren, andere Tabs zu aktualisieren ... Ja, Sie können sicherlich. Denken Sie daran - Sie haben vollen Zugriff auf den aktuell gerenderten HTML-Code innerhalb Ihrer js.erb-Vorlage, sodass es nur darum geht, jQuery zu verwenden, um den Inhalt der gewünschten Registerkarte (n) zu aktualisieren. Fügen Sie eine weitere JavaScript-Zeile hinzu, die die andere Registerkarte auswählt und deren Inhalt auf die von Ihnen benötigte Art aktualisiert. –

Verwandte Themen