2016-06-29 15 views
0

Ich erstelle eine Seite mit einer Liste von Büchern und folgen Sie der Taste auf jedem Buch.Rails Ajax auf folgen Knopf

shared/_books.html.erb

<% @books.each do |book| %> 
<%= book.name %> 
<% if book.followed_by(current_user) %> 
    <%= link_to 'Unfollow', unfollow_book_path(book), remote: true %> 
<% else %> 
    <%= link_to 'Follow', follow_book_path(book), remote: true %> 
<% end %> 
<% end %> 

Controller/books_controller.rb

def index 
@books = Book.all 
respond_to do |format| 
    format.html 
    format.js 
end 
end 

In meinem follow.js.erb, wie kann ich den Knopf unfollow Taste ändern, wenn ich klicken auf der follow Taste? Derzeit bin ich eine Methode, um die Liste der Bücher wie dies zu machen:

Bücher/follow.js.erb

$('#books').html("<%= escape_javascript(render partial: 'shared/books' , collection: @books, as: "book") %>"); 

Dies funktioniert, aber es ist die ganze Liste der Bücher Rendering wieder, die ich don Willst du keine Ideen, wie kann ich nur die Follow-Taste aktualisieren? Danke

+0

Danke, los gehts. – pyfl88

Antwort

1

Eine Möglichkeit, dies zu tun wäre, ein Div um den If/Else-Block in Ihrem Teil zu erstellen. Geben Sie diesem div eine ID, die auf der book.id basiert und daher eindeutig ist.

In Ihrer follow.js.erb, verwenden Sie die Logik von Ihnen teilweise.

<% if @book.followed_by(current_user) %> 
    $("#book-<%= @book.id %>").html("<%= link_to 'Unfollow', unfollow_book_path(@book), remote: true %>") 
<% else %> 
    $("#book-<%= @book.id %>").html("<%= link_to 'Follow', follow_book_path(@book), remote: true %>") 
<% end %> 

Möglicherweise müssen Sie Ihre Routen/Controller ändern. Ich bin nicht sicher, wie Ihr unfold_book_path und follow_book_path funktioniert.

+0

Danke für die Antwort. Wo/wie soll ich '@ book' definieren? – pyfl88

+0

Der unfold_book_path und der follow_book_path sollten jeweils eigene Methoden im Controller haben. In diesen Methoden können Sie das Buch von den Params finden. –

1

Dies ist ein perfektes Beispiel für React ist nützlich, da es eingerichtet werden kann, nur einen Teil einer Seite neu zu rendern.

Wenn Sie dies tun möchten, ohne dem Stack zusätzliche Technologie hinzuzufügen, können Sie eine Funktion einrichten, die das click-Ereignis abfängt und einen AJAX-Aufruf sendet, anstatt einen rails-Helper-Link zu verwenden ein JSON (oder ein anderes Objekt, das Sie identifizieren können), um den aktuellen Status anzuzeigen und nur den angeklickten Link zu ändern.

Ein rein manueller Ansatz könnte in etwa so aussehen, aber es gibt eine Reihe von Möglichkeiten, diesen Code zu optimieren und zu vereinfachen. Hier wird diese einfach als herausgezogen Ansicht soll veranschaulichen, was passiert ..

shared/_books.html.erb

<% if book.followed_by(current_user) %> 
    <a class = 'unfollow' href="#" onClick='followClicked(this)'>Unfollow</a> 
<% else %> 
    <a class = 'follow' href="#" onClick='followClicked(this)'>Follow</a> 
<% end %> 

Bücher/follow.js.erb

function followClicked(event){ 
    var ajax_url = event.target.hasClass('unfollow') ? <%=unfollow_book_path(book)%> : <%=follow_book_path(book)%> 
    $.ajax({ 
    url: ajax_url 
    type: 'GET' 
    }).success(function(data){ 
    if(data["new_class"] == 'unfollow'){ 
     event.target.removeClass('follow'); 
     event.target.addClass('unfollow'); 
     event.target.text("Unfollow"); 
    } else { 
     event.target.removeClass('unfollow'); 
     event.target.addClass('follow'); 
     event.target.text("Follow"); 
    } 
    }); 
} 

In Wie oben beschrieben, erwartet der Controller ein JSON, das wie folgt aussieht:

{'new_class' => 'follow'} 

Auch dies ist nur ein App oach und es gibt viele andere (einige leichter zu verstehen, dass andere;)). Ich bin mir sicher, dass jemand hier wahrscheinlich andere Ideen hat, die ebenso gut oder besser funktionieren.