我目前在我的两个表单视图中有以下script
。
<script>
$('#standard_calendar').calendar();
$('#time_calendar').calendar({type: 'time'});
</script>
我可以在哪里放置它们,以便可以访问它们但不与我的 HTML 混合?
理想情况下,您的脚本应该预先打包并连接到单个文件中,以避免多个 HTTP 请求。与其依赖于在特定页面上加载一组特定的 JavaScript,不如将数据属性或类添加到 body 元素并使用它来切换您的行为。这不仅对性能更好,而且可以避免与涡轮链接相关的问题,并在页面访问中具有持久的浏览器会话。
不久前,我为此写了一个宝石,已经有一段时间没有维护了,但我基本上通过做解决了它:
<body data-action="<%= action_name %>" data-controller="<%= controller_name %>">
$(document).on('turbolinks:load', function(){
let data = $('body').data();
// pagescript: is just the namespace for the events to avoid potential name collisions
// Use whatever you want instead
$(document).trigger('pagescript:' + data.controller + '#' + data.action, data)
.trigger('pagescript:' + data.controller + '#*', data)
.trigger('pagescript:' + '*#' + data.action , data);
});
这会在每次页面更改时触发一组自定义事件。您可以添加事件侦听器来侦听特定页面或操作:
// A specific controller_name and action
$(document).on('pagescript:controller_name#action_name', (e) => { });
// Any action belonging to a specific controller
$(document).on('pagescript:controller_name#*', (e) => { });
// Any action matching action_name
$(document).on('pagescript:*#action_name', (e) => { });
例如:
$(document).on('pagescript:users#new', (e) => {
alert("Welcome new user!");
});
但这个问题也可以通过更好的代码设计来解决。考虑可用于增强任何页面中的行为的模块,而不是编写增强特定页面上特定涂鸦的代码。
你有两个选择(我假设你已经安装了webpacker):
- 您可以在
app/javascript/components
文件夹中创建新的 js 文件。然后将此文件导入application.js
.application.js
是所有 JavaScript 的入口点 - 通过 <%= javascript_pack_tagapplication.html.erb
中的"应用程序"%> 。因此,您的脚本将在所有页面上调用。 - 或者,这只有在不使用turbolinks时才有效,您可以在
app/javascript/packs
中为脚本创建一个新文件,然后在相应的视图中,使用<%= javascript_pack_tag 'file_name' %>
调用脚本。因此,如果您调用文件calendar.js
它将是<%= javascript_pack_tag 'calendar' %>
然后,您的脚本将仅在这一个视图页面上调用。
如果您遵循第二个选项并且底部有application.html.erb
的主要<%= javascript_pack_tag 'application' %>
,则还有一个提示:
这意味着,在呈现可能导致错误的主application.js
之前调用日历脚本。避免这种情况的一种方法是在application.html.erb
中创建第二个收益率并像这样使用它:
application.html.erb
<body>
<%= yield %>
<%= render "shared/footer" %>
<%= javascript_include_tag 'application' %>
<%= javascript_pack_tag 'application' %>
<%= yield(:after_js) %>
</body>
然后,在您的视图中,您可以执行以下操作:
views/somthing/index.html.erb
...
<%= content_for :after_js do %>
<%= javascript_pack_tag 'calendar' %>
<% end %>
此流程如下所示:application.html.erb
呈现正文并包含视图文件中的 html 代码。然后,它呈现页脚(例如)。然后,它会调用可能会导入一些通用 JS 代码和包的application.js
。然后第二个收益再次调用视图中的块,该块具有日历的特定脚本。