简体   繁体   English

Rails AJAX response_to不获取JavaScript

[英]Rails AJAX respond_to not getting JavaScript back

I'm trying to implement an AJAX Acts_As_Votable update as discussed in a few other discussions, but for some reason, the format.js doesn't seem to be firing when I send the AJAX request to update the vote count. 我正在尝试实现其他一些讨论中讨论的AJAX Acts_As_Votable更新,但是由于某些原因,当我发送AJAX请求更新投票计数时,format.js似乎没有触发。

What should happen is that the image changes, but it doesn't. 应该发生的是图像改变了,但是没有改变。 Nothing changes and the page doesn't update. 没有任何变化,页面也没有更新。

The vote count is working, though, and if I refresh the page I can see it, but the upvote.js.erb and downvote.js.erb files aren't running at all. 不过,投票计数有效,如果刷新页面可以看到投票,但是upvote.js.erb和downvote.js.erb文件根本没有运行。 So it's working on the backend, the js file that should change the view just doesn't seem to be running. 因此,它正在后端运行,应该更改视图的js文件似乎并未运行。

I've tried the common solutions, like not rendering the layout and changing the order in the respond_to, but nothing seems to be making it work. 我尝试了常见的解决方案,例如不渲染布局并更改response_to中的顺序,但是似乎没有任何效果。

Any idea what's wrong? 知道有什么问题吗?

Here's the code: 这是代码:

Controller Actions 控制器动作

def upvote
  @list.upvote_by current_user
  respond_to do |format|
    format.html { redirect_to :back }
    format.js
  end
end

def downvote
  @list.downvote_by current_user
  respond_to do |format|
    format.html { redirect_to :back }
    format.js
  end
end

View 视图

<div id="upvote" class="like"> <!-- Upvote div! -->
  <%= link_to upvote_list_path(@list), method: :put, class: "btn btn-default btn-sm like", remote: true do %>
    <div id="upvote-button">
      <% if user_signed_in? and current_user.voted_up_on? @list %>
        <%= image_tag("upvote-selected.svg") %>
      <% else %>
        <%= image_tag("upvote-not-selected.svg") %>
      <% end %>
    </div>
    <div id="upvote-count">
      <%= rating(@list) %>
    </div>
  <% end %>
</div>

<div id="downvote" class="dislike"> <!-- Downvote Div -->
  <%= link_to downvote_list_path(@list), method: :put, class: "btn btn-default btn-sm dislike", remote: true do %>
    <div id="downvote-button">
      <% if user_signed_in? and current_user.voted_down_on? @list %>
        <%= image_tag("downvote-selected.svg") %>
      <% else %>
        <%= image_tag("downvote-not-selected.svg") %>
      <% end %>
    </div>
  <% end %>
</div>
</div>

upvote.js.erb (in the views/lists folder) upvote.js.erb(在views / lists文件夹中)

$('.like').bind('ajax:success', function() {

    $('#upvote-button').text(<%= image_tag("upvote-selected.svg") %>);

});

$('.dislike').bind('ajax:success', function() {

    $('#downvote-button').text(<%= image_tag("downvote-not-selected.svg") %>);

});

downvote.js.erb downvote.js.erb

$('.like').bind('ajax:success', function() {

    $('#upvote-button').text(<%= image_tag("upvote-not-selected.svg") %>);

});

$('.dislike').bind('ajax:success', function() {

    $('#downvote-button').text(<%= image_tag("downvote-selected.svg") %>);

});

Any help would be greatly appreciated. 任何帮助将不胜感激。 Thanks!! 谢谢!!

You're mixing two things here: rendering JS on an AJAX call and actually executing it. 您在这里混合了两件事:在AJAX调用上呈现JS并实际执行它。

What happens at the moment is that you're rendering JS but the code that binds the ajax:success event has never actually been executed in the client so the browser doesn't know what to do with the JS response. 目前发生的事情是您正在渲染JS,但是绑定ajax:success事件的代码实际上尚未在客户端中执行,因此浏览器不知道如何处理JS响应。

First, you need to register the event handler for ajax:success in your regular JS code ( application.js or some other appropriate part of your JS structure). 首先,您需要在常规JS代码( application.js或JS结构的其他适当部分)中为ajax:success注册事件处理程序。 Then you can either just decide to eval the response of the server wholesale - it would then just contain the code doing the text replacement - or even decide to return a JSON structure with data appropriate to your use case (to stay simplistic, a hash with image URLs for both the "like" and "dislike" button). 然后,您可以决定eval服务器批发的响应-然后只包含进行文本替换的代码-甚至决定返回一个JSON结构,其中包含适合您用例的数据(为简单起见,使用“喜欢”和“不喜欢”按钮的图片网址)。

Okay based on the tips in ma_il's answer, I figured out a much simpler way to do this. 好的,根据ma_il的提示,我找到了一种更简单的方法。 I completely missed that my original solution was never running the bind the first time, so thank you for that :). 我完全想念我的原始解决方案从未第一次运行绑定,所以谢谢您:)。 I think I could probably make this even simpler with the JSON suggestion... I just need to figure that out. 我想我可以通过JSON建议使它变得更简单...我只需要弄清楚这一点。

First I changed the controller actions a little since I didn't need the HTML: 首先,由于不需要HTML,我对控制器的动作做了一些更改:

def upvote
  @list.upvote_by current_user
  respond_to do |format|
    format.js
  end
end

def downvote
  @list.downvote_by current_user
  respond_to do |format|
    format.js
  end
end

Then the upvote.js.erb and downvote.js.erb files look like this (this is the upvote one): 然后upvote.js.erbdownvote.js.erb文件如下所示(这是upvote之一):

$("#upvote-button").html("<%= escape_javascript( image_tag('upvote-selected.svg') ) %>");
$("#downvote-button").html("<%= escape_javascript( image_tag('downvote-not-selected.svg') ) %>");
$("#upvote-count").html("<%= rating(@list) %>");
$("#num-ratings").html("<%= @list.votes_for.size %> Ratings");

And everything seems to work! 一切似乎都正常!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM