使用remote = true从JS更新Rails视图

时间:2017-10-15 10:13:39

标签: javascript jquery ruby-on-rails

我在Rails视图中有这段代码:

(稍微简化以适应问题)

<%= link_to "FAV", :action => 'make_fav', 
    remote: true,  data: {old_state: "NOTFAV", 
    product: product.id} %>

在我的控制器中工作并调用方法“make_fav”。此方法更新数据库并设置实例变量@newstate =“FAV”

make_fav.js.erb中的

我可以看到此实例变量已设置

<% puts "Newstate is #{@newstate}" %>

在我的index.html.erb中,我有

<td id='<%= "favourite-#{product.id}" %>' >
  <% if current_user.products.exists?(product.id) %>
      <i class="fa fa-star" %></i>
  <% else %>
      <i class="fa fa-star-o" %></i>
  <% end %>
</td>

现在我应该如何(在make_fav.js.erb中)更新id为“favorite - #{product.id}”的td以反映@newstate变量?

我尝试过像

这样的事情
<% @key = "#favourite-#{@product.id}" %> 
<% x = "<i class='fa fa-star' id='favourite-#{@product.id}></i>" %>

$('<%= @key %>').html("<%= escape_javascript (x) %>");

但是正如你所看到的,当涉及到javascript时,我感到很茫然......

基本上,我想将内容更新为

<i class="fa fa-star" %></i>

如果@newstate是“FAV”,否则

<i class="fa fa-star-o" %></i>

我觉得我很亲近,但感谢任何帮助!

此外,如果有更好/更“顽固”的方式,我希望听到它。

1 个答案:

答案 0 :(得分:2)

你的推理与解决方案相差无几。您似乎正在计算要查找的元素的id,但是您想要更新该ID中的i元素。因此,make_fav.js.erb上的一个小改动可以解决问题。尝试更改为:

(function() {
  var id = "#favourite-<%= @product.id %> i";
  if ($(id).hasClass('fa-star-o')) {
    $(id).addClass('fa-star').removeClass('fa-star-o');
  } else {
    $(id).addClass('fa-star-o').removeClass('fa-star');
  }
})();

在此解决方案中,我们首先定义您要查找的i的选择器(i中的favourite-id并交换该类(如果它是{{1}它转到fa-star,反之亦然。)

请注意,在这种情况下,不应使用fa-star-o,而应使用数据的新状态(我只是不知道它的外观如何),但是{{1}可能看起来像:

$(id).hasClass('fa-star-o')

这将是首选方式,因为您不依赖于UI的状态,而是依赖于数据的状态。