js.erb 文件正在执行两次。 Ruby on Rails - private_pub

Posted

技术标签:

【中文标题】js.erb 文件正在执行两次。 Ruby on Rails - private_pub【英文标题】:js.erb file is executing two times . Ruby on Rails - private_pub 【发布时间】:2016-02-27 23:45:35 【问题描述】:

我正在开发chating 模块。为此,我使用了private_pub gem。在这个模块中,我制作了三个频道,但我不能在这里提及所有这些,因为它会显示一个非常非常大的页面。所以让我们坚持一个频道。

我单击具有频道"<%= subscribe_to "/conversations/send_invitation" %>" 的链接,然后ajax 工作并转到"conversations/send_invitation"(仅一次-没关系),在我的"/conversations/send_invitation" 中我有

def send_invitation
 @conversation = Conversation.new(conversation_params)
 respond_to do |format|
 format.js  render :layout => false 
 format.html
 end
end

然后在我的send_invitation.js.erb 文件中,我有以下内容

<% publish_to "/conversations/send_invitation" do %>
var recipient_id = "<%=@conversation.recipient.id %>";
var current_temp_user = $("#current_temp_user").val();

if(recipient_id == current_temp_user)
console.log('here')
$("#invitation_div").html("<%=j(render :partial => '/restaurants/invitation')%>");
    card_modal = $('#invitation_card').modal();
    card_modal.modal('show');

<% end %>

这是我的application.js 文件

//= require jquery
// require jquery-ui
//= require jquery_ujs
// require turbolinks
//= require bootstrap
//= require jquery.raty
//= require private_pub
//= require_tree .

模态显示在recipient side(这很好)。

现在的问题是我可以在firefox console/html 中看到两个modalsame id。而buttonsclosing/submitmodal 也停止工作。我的send_invitation.js.erb 文件中的console.log 也显示了两次console.log 结果,因此很明显js.erb 文件正在执行两次。但需要注意的是ajax 只运行了一次。我在上面浪费了几个小时,发现只有This link 对我也不起作用,因为当我删除jquery.jsjquery_ujs.js 时,它会给我错误

【问题讨论】:

你的服务器日志说什么?操作send_invitation 执行一次还是两次?也许您要订阅该频道两次?您可以在浏览器的开发者控制台中进行调试。 @coorasse 不,它只调用了一次send_invitation 那么,如果你订阅了两次频道,你能在开发者控制台中看到吗? 我在同一个页面订阅了两个不同的频道 - 有什么问题吗 执行send_invitation方法时服务器的响应是什么? 【参考方案1】:

我找不到解决方案,但我认为值得有人告知实际问题。 就我而言,问题是我在同一页面上制作了两个频道,这就是为什么它要与瘦服务器握手两次。

注意但在一般情况下,如果我们两次包含 js 文件,也会发生这种情况。

【讨论】:

在同一页面上制作频道是什么意思?在页面上有两次 和一个会话表单,或者只有一次 但有两个会话表单?就我而言,这肯定是 turbolinks 问题。如果我重新加载整页,一切正常,但是如果我在转到另一个应用程序页面然后返回后创建了 conversation.message,它会显示更多次(它只将 1 条消息保存到数据库,只有问题带显示)。有什么猜测吗? Imran,看来我可以解决这个问题。看看我的回答!【参考方案2】:

使用$(document).on('keydown', '.chatboxtextarea', function (event)....);,我的消息对象只创建了一次,但根据我在没有重新加载完整页面的情况下返回页面的次数而显示了多次。 为了在 js.erb 文件中解决这个问题,我添加了 event.handled 来检查是否已经附加了部分。

应用程序.js

//= require jquery
//= require jquery-ui
//= require jquery_ujs
//= require turbolinks
//= require jquery.remotipart
//= require chat
//= require refile
//= require bootstrap-sprockets
//= require private_pub
//= require local_time
//= require moment
//= require fullcalendar
//= require bootstrap-datetimepicker
//= require_tree .

js文件

 //submitting chat message (it's OUTSIDE $(document).on('page:change'..)
 //bind submit to document --> not affected by turbolinks
$(document).on('keydown', '.chatboxtextarea', function (event) 
  var id = $(this).data('cid');
  checkInputKey(event, $(this), id);
);

function checkInputKey(event, chatboxtextarea, conversation_id) 
  if (event.keyCode == 13 && event.shiftKey == 0) 
    event.preventDefault();

    //checking if field is empty and submitting the form
    message = chatboxtextarea.val();
    message = message.replace(/^\s+|\s+$/g, "");
    if (message != '') 
      $('#conversation_form_' + conversation_id).submit();
    
  

html.erb 表单

<div class="chatboxinput">
  <%= form_for([@conversation, @message], :remote => true, :html => id: "conversation_form_#@conversation.id") do |f| %>
    <%= f.text_area :body, class: "chatboxtextarea", "data-cid" => @conversation.id %>
  <% end %>
</div>
......
<%= subscribe_to conversation_path(@conversation) %>

_message.html.erb

<li class="<%= self_or_other(message) %>">
  <div class="chatboxmessagecontent">
    <p>
      <%= message.body %>
    </p>
  </div>
</li>

create.js.erb

<% publish_to @path do %>
  var id = "<%= @conversation.id %>";
  var chatbox = $(".chatboxcontent");
  var lastMessage = chatbox.children().last();

  //with this one message will be displayed only once
  if(event.handled !== true) 

    $message = $('<%= j render @message %>');
    chatbox.append($message);
    chatbox.scrollTop(chatbox[0].scrollHeight);

    //for displaying incoming and outgoing messages differently
    if(sender_id != receiver_id) 
        chatbox.children().last().removeClass("self").addClass("other");
        chatbox.scrollTop(chatbox[0].scrollHeight);
    

    event.handled = true;
  ;
<% end %>

【讨论】:

【参考方案3】:

使用 unbind 方法删除不想要的/多个要与您的事件一起执行的调用。这会成功的。但多次调用背后的原因尚不清楚。

$( "#foo" ).unbind( "click", handler );

希望对你有帮助。

【讨论】:

【参考方案4】:

改用这个 gem

gem "private_pub", :git =&gt; 'https://github.com/ryleto/private_pub.git'

【讨论】:

以上是关于js.erb 文件正在执行两次。 Ruby on Rails - private_pub的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails 的移动版视图

使用 ajax 刷新页面时,Ruby on Rails 失败

Rails update.js.erb 不执行 javascript

js.erb 文件未呈现其内容

Rails js.erb 文件未执行

如何将javascript变量传递给嵌入式ruby?