在 Rails 5.2 应用程序中,我应该将特定页面的 JavaScript 放在哪里?



我目前在我的两个表单视图中有以下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):

  1. 您可以在app/javascript/components文件夹中创建新的 js 文件。然后将此文件导入application.js.application.js是所有 JavaScript 的入口点 - 通过 <%= javascript_pack_tagapplication.html.erb中的"应用程序"%> 。因此,您的脚本将在所有页面上调用。
  2. 或者,这只有在不使用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。然后第二个收益再次调用视图中的块,该块具有日历的特定脚本。

最新更新