在我的应用中,用户可以将产品标记为收藏,然后取消标记。
我希望当用户喜欢产品时,图标颜色会改变,并且喜欢的计数器会在不重新加载的情况下增加。
计数器在导航栏中
<%= @favorites.count %>
这是 products / indx.html.erb
<% @products.each do |product| %>
<div class="header_card">
<%= link_to clients_product_path(product) do %>
<div id="like_unlike">
<% if product.favoriting_users.include? current_user %>
<% fav = product.favorites.find { |fav| fav.user_id == current_user.id} %>
<%= link_to clients_product_favorite_path(product, fav), method: :delete , remote: true do %>
<i class= "fa fa-heart favorite-active"></i>
<% end %>
<% else %>
<%= link_to clients_product_favorites_path(product), method: :post, remote: true do %>
<i class= "fa fa-heart not-favorite"></i>
<% end %>
<% end %>
</div>
<div id="carousel_<%= product.id%>" class="carousel slide" data-ride="carousel" data-interval="false">
<div class="carousel-inner">
<% product.attachments.each do |img| %>
<div class="carousel-item <%= 'active' if img == product.attachments[0] %>">
<%= image_tag img.url, class: "product_suggestion" %>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
<% end %>
这是我的 favorites_controller.rb
class Clients::FavoritesController < ApplicationController
before_action :find_favorite, only: [:destroy]
def index
@favorites = Favorite.where(user: current_user).all
end
def create
@product = Product.find(params[:product_id])
@user = current_user.id
favorites = {user_id: @user, product_id: @product.id}
@favorite = Favorite.new(favorites)
@favorite.save
if @favorite.save
respond_to do |format|
format.js
format.html {redirect_to clients_products_path(@product)}
end
else
respond_to do | format|
format.js
format.html {redirect_to clients_products_path, alert: "HOPHOP" }
end
end
end
def destroy
if @favorite.destroy!
respond_to do |format|
format.js
end
end
end
private
def find_favorite
find_product
@favorite = @product.favorites.find(params[:id])
end
end
试图使问题更清晰...
这个想法是,当喜欢某个产品时,应该增加收藏夹计数器<%= @favorites.count %>
而不进行重新加载。
当不再喜欢时,计数器应递减
我有两个图标,根据是否喜欢,只有一个可见。
我的产品/index.html.erb中的我有这些行(上面的完整代码)
当尚不喜欢某个产品时,将显示此图标:
<%= link_to clients_product_favorites_path(product), method: :post, remote: true do %>
<i class= "fa fa-heart not-favorite"></i>
<% end %>
喜欢该图标时,该图标应重新加载...
<% fav = product.favorites.find { |fav| fav.user_id == current_user.id} %>
<%= link_to clients_product_favorite_path(product, fav), method: :delete , remote: true do %>
<i class= "fa fa-heart favorite-active"></i>
<% end %>
是否可以在create.js.erb中传递一些rails代码,然后将方法post的link_to更改为方法delete的链接
create.js.erb *在这里,我只是通过更改css来伪造图标更改。...这是我的hack,但是我需要检索可以使用delete方法的其他图标_
$('.header_card').bind('.not-favorite').bind('ajax:success', function(){
$(this).find(".not-favorite").css('color', 'red');
$("#likes_counter").html("<%= @favorites.count %>");
});
destroy.js.erb 与以下相同
$('.header_card').bind('.favorite-active').bind('ajax:success', function(){
$("#likes-count").html("<%= @favorites.count %>");
$(this).find(".favorite-active").css('color', 'gray');
});
答案 0 :(得分:2)
首先,我建议您像这样简化控制器:
def create
@product = Product.find(params[:product_id])
@favorite = current_user.favorites.create(product: @product) #I guess you have that association already set up
respond_to do |format|
format.js
format.html {
if @favorite.persisted?
redirect_to clients_products_path(@product)
else
redirect_to clients_products_path, alert: "HOPHOP"
}
end
end
只是减少可能出错的行数。
在视图上,不必将回调函数绑定到ajax:success
事件,在呈现该视图的上下文中,您已经在该事件内。只需添加代码行来更新视图,jQuery将执行它们。
# create.js.erb
$('.header_card .not-favorite').toggleClass('not-favorite').toggleClass('favorite-active');
$("#likes_counter").html("<%= @product.favorites.count %>");
# destroy.js.erb
$('.header_card .favorite-active').toggleClass('not-favorite').toggleClass('favorite-active');
$("#likes-count").html("<%= @product.favorites.count %>");
请注意类的更改(您可以使用CSS设置图标,然后只需要在按钮上设置propper类即可完成)和计数(您在未定义的地方使用@favorites
)在控制器上)。
答案 1 :(得分:0)
这是按预期完成工作的原因:
我首先使用#id将链接放入div
<div class="like_unlike">
<% if product.favoriting_users.include? current_user %>
<div id="unlike_<%= product.id %>">
<% fav = product.favorites.find { |fav| fav.user_id == current_user.id} %>
<%= link_to clients_product_favorite_path(product, fav), method: :delete , remote: true do %>
<i class= "fa fa-heart favorite-active"></i>
<% end %>
</div>
<% else %>
<div id="like_<%= product.id %>">
<%= link_to clients_product_favorites_path(product), method: :post, remote: true do %>
<i class= "fa fa-heart not-favorite"></i>
<% end %>
</div>
<% end %>
create.js.erb
$('#header_card_<%= @product.id %>').bind('.not-favorite').bind('ajax:success', function(){
if("<%= @favorites.count %>" === "1"){
$("#like_<%= @product.id %>").empty();
$("#header_card_<%= @product.id %>").find("#like_<%= @product.id %>").replaceWith("<div class='unlike_<%= @product.id %>'><a data-remote='true' rel='nofollow' data-method='delete' href='/clients/products/<%= @product.id %>/favorites/<%= @favorite.id %>'><i class= 'fa fa-heart favorite-active'></i></a></div>");
$("#header_card_<%= @product.id %> .not-favorite").toggleClass('not-favorite').toggleClass('favorite-active');
$("#likes_counter").html("<%= @favorites.count %>");
location.reload();
}
else {
$("#like_<%= @product.id %>").empty();
$("#header_card_<%= @product.id %>").find("#like_<%= @product.id %>").replaceWith("<div class='unlike_<%= @product.id %>'><a data-remote='true' rel='nofollow' data-method='delete' href='/clients/products/<%= @product.id %>/favorites/<%= @favorite.id %>'><i class= 'fa fa-heart favorite-active'></i></a></div>");
$("#header_card_<%= @product.id %> .not-favorite").toggleClass('not-favorite').toggleClass('favorite-active');
$("#likes_counter").html("<%= @favorites.count %>");
}
});
destroy.js.erb
$('#header_card_<%= @product.id %>').bind('.not-favorite').bind('ajax:success', function(){
if('<%= @favorites.count %>' === "0" || "<%= @favorites.first %>"){
$("#likes_counter").html("<%= @favorites.count %>");
$("#header_card_<%= @product.id %> .favorite-active").toggleClass('favorite-active').toggleClass('not-favorite');
$("#unlike_<%= @product.id %>").empty();
$("#header_card_<%= @product.id %>").find("#unlike_<%= @product.id %>").replaceWith("<div class='like_<%= @product.id %>'><a data-remote='true' rel='nofollow' data-method='post' href='/clients/products/<%= @product.id %>/favorites %>'><i class= 'fa fa-heart favorite-active'></i></a></div>");
location.reload();
}
else {
$("#likes_counter").html("<%= @favorites.count %>");
$("#header_card_<%= @product.id %> .favorite-active").toggleClass('favorite-active').toggleClass('not-favorite');
$("#unlike_<%= @product.id %>").empty();
$("#header_card_<%= @product.id %>").find("#unlike_<%= @product.id %>").replaceWith("<div class='like_<%= @product.id %>'><a data-remote='true' rel='nofollow' data-method='post' href='/clients/products/<%= @product.id %>/favorites %>'><i class= 'fa fa-heart favorite-active'></i></a></div>");
}
});