首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何告诉rails不要在我的应用程序中预编译/缓存.js.erb文件?

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

Stack Overflow用户
提问于 2017-12-21 14:13:17
回答 2查看 736关注 0票数 5

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

这里是我的messages.js.erb文件

代码语言:javascript
运行
复制
//**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在第一次加载后缓存(precompiling?)该文件(asset?),并在每次请求时为其提供服务。

因此,问题是:每次创建一个新的聊天室时,如果我想让它流(即能够将消息立即发送到聊天室的每个参与者),我需要手动更改文件(添加空白,或者添加注释或记录到控制台,something)并保存它,以便rails认为文件已经更改并重新加载它,从而再次迭代包含新创建的聊天室的所有Chatroom

否则,当我在聊天室中的消息上发布(点击enter)时,还没有流(因为缓存的版本看不到),我将得到一个

未定义的TypeError:无法读取属性'setChatroomId‘的未定义在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代码(为简洁而修剪的重复行)

代码语言:javascript
运行
复制
  $(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不要预编译/缓存它,这样我就可以创建聊天室并在运行过程中从它们中流?

EN

回答 2

Stack Overflow用户

发布于 2018-09-07 06:15:02

我想您使用了来自https://www.thegreatcodeadventure.com/rails-5-action-cable-with-multiple-chatroom-subscriptions/的教程,这是一个很好的教程。您应该解决这个问题,而不是通过更改预编译。相反,更有效地利用渠道。

例如,从外部执行该方法。使用帮助方法只获得所需的房间。

代码语言:javascript
运行
复制
subscripeToChannels(<%= raw chatrooms_for_client %>)

在订阅方法中,检查是否已经订阅。

代码语言:javascript
运行
复制
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;
    }
  }

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

代码语言:javascript
运行
复制
subscripeToChannels(<%= raw chatrooms_for_client %>)

对我来说,这是以一种更清洁的方式解决的

票数 2
EN

Stack Overflow用户

发布于 2017-12-21 19:33:13

messages.js.erb文件移动到lib/assetsvendor/assets目录。

来自文档

库/资产或供应商/资产下的...assets可以通过应用程序清单进行包含,但不再是预编译数组的一部分。

确保它没有列在你的application.js中,而且你应该做得很好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47926788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档