Rails 4中的Ajax

4
我有一个应用程序,允许用户点赞。当有人点赞时,请求可以正常工作,但是视图不会更新,除非我刷新页面。我卡在这个问题上了。这是我目前的代码:

Javascript

$('.favorite').on('click', function() {
  var $heart = $(this).find('.fa');
  $heart.removeClass('fa-heart-o').addClass('fa-heart');
  // POST request to server to create favorite in db
  $.post('/favorites', {
    favorite: { post_id: $(this).attr('data-id') }
  },
  function(data) {
    console.log(data);
  });
});

控制器
def create
  post = Post.find_by_id(favorite_params[:post_id])
  if current_user.favorite_posts.include? post
    render json: {}, status: :bad_request
  else
    @favorite = current_user.favorites.new(favorite_params)
    if @favorite.save
      render json: @favorite
    else
      render json: { errors: @favorite.errors.full_messages }, status: :unprocessable_entity
  end
end

结束

这是视图

<% if current_user.favorite_posts.include? post %>
  <span class="fa fa-heart"> <%= post.favorites.count %></span>
<% else %>
  <span class="fa fa-heart-o"> <%= post.favorites.count %></span>
<% end %>

非常感谢您的帮助。

谢谢!


1
更新视图的代码在哪里? - violarium
似乎没有需要创建的收藏夹。当我阅读您的代码时,我发现在create函数中不仅需要传递post_id,还需要传递favorite_params。您是如何获取favorite_params的?请展示您完整的控制器。谢谢。 - akbarbin
3个回答

6

执行以下操作:

var new_count;
new_count = function() {
  # your script
};



$(document).ready(new_count);
$(document).on('page:load', new_count);

这个问题似乎与turbolink有关,查看此链接


感谢你的帮助,Arv! - robb

2

与其

function(data) {
  console.log(data);
  });

您应该更新您的视图。您可能需要检查错误,如果没有错误,则使用jQuery选择器 $( "... span.fa" ).text(new_count) 更新内容的span。

通过这种方法,您可以将new_count的值计算为(previous_count_in_the_span+1),但如果不会导致性能问题,则可能希望在响应中返回计数值。


感谢您的回复,Dutow。 - robb

2
有两种解决方案:

  1. 使用浏览器内ajax调用视图更改
  2. 使用Rails UJS功能在服务器上运行视图更改

我认为你最大的问题是没有任何功能可以在成功请求后更改你的视图。以上两个选项是让其正常工作的必要条件,因此我将在这里详细介绍它们:


Ajax

Ajax会为您发送请求;但您仍需管理其响应和功能:

$.post('/favorites', { favorite: { post_id: $(this).attr('data-id') }},
.done( function(data) {
  /* Manipulate your view here */
  $("span.fa").text(data);
  console.log("Success");
});

你必须记住,Ajax只是一个异步请求。也就是说,JavaScript会像微型浏览器一样代表你向服务器发送数据。

然后它将从服务器接收响应(可能包含您想要的数据)... 然后您需要使用这些数据来操作您的视图。


JS

另一种方法涉及Rails UJS系统。也就是说,在控制器动作触发后,您可以运行JavaScript ERB模板。

这将使您能够根据需要操作视图,而无需编辑当前的JavaScript:

$.post('/favorites', { favorite: { post_id: $(this).attr('data-id') }}
  .done( function(data) { console.log(data); });


#app/controllers/favourites_controller.rb
class FavouritesController < ApplicationController
   def create
     ...
     respond_to do |format|
        if @favorite.save
          format.js #-> invokes /views/favourites/create.js.erb
          format.json { render json: @favorite }
        else
          format.js
          format.json { render json: { errors: @favorite.errors.full_messages }, status: :unprocessable_entity }
  end
end

接下来,您可以使用app/views/favourites/create.js.erb来操作您的视图:

#app/views/favourites/create.js.erb
$("span.fa").hide();

1
非常感谢你,Rich。这真的很有帮助。我不喜欢“.done”这一部分,但是一旦我把它删除了,它就可以工作了!祝你周末愉快。 - robb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接