Rails ajax on按钮

时间:2016-06-29 15:37:31

标签: javascript jquery ruby-on-rails ajax

我正在创建一个包含书籍列表的页面,并在每本书上按下按钮。

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 %>

控制器/ books_controller.rb

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

在我的follow.js.erb中,当我点击unfollow按钮时如何将按钮更改为follow按钮?目前我正在使用一种方法来呈现这样的书籍列表:

书籍/ follow.js.erb

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

这是有效的,但是它再次呈现了整个书籍列表,我不想要,任何想法如何才能刷新关注按钮?感谢

2 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是在部分中的if / else块周围创建一个div。给这个div一个基于book.id的id,因此是唯一的。

在你的follow.js.erb中,重用你部分的逻辑。

<% 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 %>

您可能需要更改路线/控制器。我不确定你的unfollow_book_path和follow_book_path是如何工作的。

答案 1 :(得分:1)

这是React有用的完美示例,因为它可以设置为仅重新呈现页面的一部分。

如果您希望在不向堆栈添加额外技术的情况下执行此操作,则可以设置一个拦截click事件并发送AJAX调用而不是使用rails helper链接的函数,然后让控制器发回一个JSON(或您可以识别的其他一些对象)指示当前状态并仅修改单击的链接。

纯粹的手动方法可能看起来像这样,但有许多方法可以优化和简化此代码。在这里,这只是一个用于说明正在发生的事情的绘制视图..

共享/ _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 %>

书籍/ 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");
    }
  });
}

在上面,控制器应该返回一个看起来像这样的JSON:

{'new_class' => 'follow'}

同样,这只是一种方法,还有很多其他方法(其中一些更容易理解;))。我相信这里的某些人可能还有其他想法可以效用,或更好。