在 Rails 4 应用程序中,我使用 link_to 通过 json 发送对帖子的赞成票。
这是我的帖子 Controller 中的内容:
def upvote
@post = Post.find(params[:id])
@post.liked_by current_user
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { count: @post.get_upvotes.size } }
end
end
这是我的看法
<%= link_to like_post_path(post), method: :put, class: 'vote', remote: true, data: { type: :json } do %>
<%= image_tag('vote.png') %>
<%= content_tag :span, post.get_upvotes.size %>
<% end %>
<script>
$(document)
.on('ajax:send', '.vote', function () { $(this).addClass('loading'); })
.on('ajax:complete', '.vote', function () { $(this).removeClass('loading'); })
.on('ajax:error', '.vote', function(e, xhr, status, error) { console.log(status); console.log(error); })
.on('ajax:success', '.vote', function (e, data, status, xhr) {
$(this).find("span").html(data.count);
$(this).find("img").attr("src", '<%= asset_path 'voted.png' %>');
});
</script>
当我点击链接时,投票会以 JSON 请求的形式进行,我在日志中看到了这一点:
Processing by PostsController#upvote as JSON
但由于某种原因,我的 JavaScript 片段无法正常工作。计数器或图标都不会更新。 我该如何解决这个问题?这是否与涡轮链接有关,是否与我放置 JavaScript 的位置有关?
最佳答案
在 Rails 中,您可以通过 JavaScript 响应来执行类似的任务。添加您的respond_to
一个format.js
类似于format.html
然后查看upvote.js.erb
看起来像:
(function() {
var postId = "#post-<%= @post.id %>";
$(postId).find(".vote").find("span").text("<%= @post.get_upvotes.size %>");
$(postId).find(".vote").find("img").attr("src", "<%= asset_path "voted.png" %>");
})();
我已将您的电话更改为 .html
至.text
由于您实际上并未在元素内设置任何 HTML,因此没有理由调用 .html
.
本文还假设存在某种机制来识别投票链接所属的帖子(在示例中,父帖子元素的 ID 为“post-#”,其中 # 是帖子对象的 ID)。
编辑
如果我从事这个项目,我会做出两个改变。首先我会附上voted.png
.vote
的路径元素作为数据属性。 data-voted-image-src="<%= asset_path "voted.png" %>"
。接下来,我永远不会在返回中传递数字,因为没有理由这样做。单击投票后,假设请求成功,您可以在前端处理所有事情。这就避免了所有这些潜在的麻烦。虽然我意识到从当前所必须的更改到添加数据属性并不是一个巨大的飞跃,但我只是发现它比在 JavaScript 中更具语义。
投票链接上的点击操作将变为:
// Assume all posts have a class 'post'
// I'm also using 'one' because once they vote they don't need to anymore
$(".post").find(".vote").one("click", function(e) {
var count = parseInt($(this).find("span").text()),
votedSrc = $(this).data("voted-image-src");
$(this).find("img").attr("src", votedSrc);
$(this).find("span").text(count + 1);
});
现在不需要服务器响应,您可以将 JSON 响应更改为 {success: true}
或者简单的东西。
关于ruby-on-rails - Ajax:成功无法在 Rails 应用程序中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28006668/