javascript - 我如何告诉 Rails 不要在我的应用程序中预编译/缓存 .js.erb 文件?

标签 javascript ruby-on-rails asset-pipeline actioncable precompile

我的 app/assets/javascripts/channels 文件夹中有一个 messages.js.erb 文件,它应该生成代码以从数据库中获取每个聊天室并为该聊天室创建 channel 订阅。

这是我的 messages.js.erb 文件

//**app/assets/javascripts/channels/messages.js.erb**

$(document).on('turbolinks:load', function() {
  submitNewMessage();
});

<% Chatroom.all.each do |chatroom| %>
  App['room' + <%=chatroom.id%>] = App.cable.subscriptions.create({channel: 'MessagesChannel', room: <%=chatroom.id%>}, {
  received: function(data) {
   $("[data-chatroom='" + this.chatroomId + "']").removeClass('hidden');
    return $("[data-chatroom='" + this.chatroomId + "']").append(data.message);
  },

  setChatroomId: function(chatroomId) {
    this.chatroomId = chatroomId;
  }
});

<% end %>

function submitNewMessage(){
  //console.log(uid);
  $('textarea#message_content').keydown(function(event) {
    if (event.keyCode === 13) {
        var msg = event.target.value;
        var chatroomId = $("[data-chatroom]").data().chatroom;
        var uid = $('#uid').val();
        //console.log(uid);
        App['room' + chatroomId].setChatroomId(chatroomId);
        App['room' + chatroomId].send({message: msg, chatroom_id: chatroomId, user_id: uid});
        $('[data-textarea="message"]').val(" ");
        return false;
     }
  });
}

最好,每次创建新聊天室时都应重新加载此文件,但 rails 会在第一次加载和服务后缓存(预编译?)文件(asset?)它应每个要求。

所以,问题是:每次创建一个新的聊天室时,如果我希望它流式传输(即能够发布消息以立即流式传输给该聊天室的每个参与者),我需要手动更改文件(通过添加空格,或添加注释或记录到控制台,something)并保存它以便 rails 认为文件已更改并重新加载它,从而遍历所有 Chatrooms 再次包含新创建的聊天室。

否则,当我在尚未流式传输的聊天室中发布(按回车)消息时(因为缓存版本无法看到它),我得到一个

Uncaught TypeError: Cannot read property 'setChatroomId' of undefined at HTMLTextAreaElement. (messages.self-cbf13df66ead12b7956faa24e880ce07c0289634216a096fafd4ac1c6d262f43.js?body=1:436) at HTMLTextAreaElement.dispatch (jquery-1.11.3.min.self-ad66c584c2469d2bb527ba7aef5893549f1554ccc8ab3ccb43bd09ce8c3bf7a1.js?body=1:5) at HTMLTextAreaElement.r.handle (jquery-1.11.3.min.self-ad66c584c2469d2bb527ba7aef5893549f1554ccc8ab3ccb43bd09ce8c3bf7a1.js?body=1:5)

在我的浏览器控制台(开发者工具)中。错误来源是:

这是生成的 messages.js 代码(为简洁起见,重复行被删减)

  $(document).on('turbolinks:load', function() {
      submitNewMessage();
    });



   App['room' + 1] = App.cable.subscriptions.create({channel: 'MessagesChannel', room: 1}, {
  received: function(data) {
   $("[data-chatroom='" + this.chatroomId + "']").removeClass('hidden');
    return $("[data-chatroom='" + this.chatroomId + "']").append(data.message);
  },

  setChatroomId: function(chatroomId) {
    this.chatroomId = chatroomId;
  }
});
  .
  .
  .
  .
  .
  .
  .
  App['room' + 37] = App.cable.subscriptions.create({channel: 'MessagesChannel', room: 37}, {
  received: function(data) {
   $("[data-chatroom='" + this.chatroomId + "']").removeClass('hidden');
    return $("[data-chatroom='" + this.chatroomId + "']").append(data.message);
  },

  setChatroomId: function(chatroomId) {
    this.chatroomId = chatroomId;
  }
});


function submitNewMessage(){
  //console.log(uid);
  $('textarea#message_content').keydown(function(event) {
    if (event.keyCode === 13) {
        var msg = event.target.value;
        var chatroomId = $("[data-chatroom]").data().chatroom;
        var uid = $('#uid').val();
        App['room' + chatroomId].setChatroomId(chatroomId); // <-- line 436
        App['room' + chatroomId].send({message: msg, chatroom_id: chatroomId, user_id: uid});
        $('[data-textarea="message"]').val(" ");
        return false;
     }
  });
}

我知道这个错误很明显,因为 App['room' + 38] 还没有为我们试图发布消息的 id 为 38 的新聊天室定义 (在这里,所有 id > 37) 的聊天室

但是我如何让 Rails 理解每次创建新聊天室时都需要重新加载此文件。如果不是每次,那么每次请求?基本上,告诉 rails 不要预编译/缓存它,这样我就可以创建聊天室并随时随地从中流式传输?

最佳答案

我猜你使用了 https://www.thegreatcodeadventure.com/rails-5-action-cable-with-multiple-chatroom-subscriptions/ 中的教程这是一个很好的。 你应该解决这个问题而不是改变预编译。而是更有效地支持 channel 。

例如从外部执行方法。使用辅助方法仅获取所需的房间。

subscripeToChannels(<%= raw chatrooms_for_client %>)

在订阅方法中检查您是否尚未订阅。

for (var i = 0; i < App.cable.subscriptions.subscriptions.length; i++) {
    var s = App.cable.subscriptions.subscriptions[i]
    var JSONObject = JSON.parse(s.identifier);
    var room = JSONObject["room"];
    if (room == chatroomId)
    {
      preventMultipleSubscripe = true;
    }
  }

如果创建了新房间,您可以在 create.js.erb 文件中再次执行 subscripeToChannels。

subscripeToChannels(<%= raw chatrooms_for_client %>)

对我来说,这以一种更简洁的方式解决了它

关于javascript - 我如何告诉 Rails 不要在我的应用程序中预编译/缓存 .js.erb 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47926788/

相关文章:

asp.net - 如何开始创建选择脚本, "inspect like what firebug do"?

javascript - MVC jquery 自动完成多个值仅适用于第一次

javascript - 在其他单元格之间共享一个表格单元格 HTML5

ruby-on-rails - 在 Rails 中跟踪 session 时遇到问题

ruby-on-rails - rails 3.2 LESS CSS 和 heroku?

ruby-on-rails - Rails 5 Assets 未在生产中加载

javascript - 如何使用js通过cookie发送参数

ruby-on-rails - Rails - 我需要一个复选框来更改数据库中的字段

ruby-on-rails - 自动文件上传到网站

javascript - 包括页面特定 Assets