我应该如何只在一页上包含一个咖啡脚本文件?

Posted

技术标签:

【中文标题】我应该如何只在一页上包含一个咖啡脚本文件?【英文标题】:how should I include a coffeescript file on only one page? 【发布时间】:2012-01-07 05:16:45 【问题描述】:

编辑:一年后,如果我要再次这样做,我会使用 curl.js 而不是 Rails 资产管道。

相关:Best way to add page specific javascript in a Rails 3 app?

我正在编写一个应用程序并使用coffeescript 来生成所有的js。这就是为什么相关问题不能满足我的需要。

我希望能够将一个咖啡脚本文件放在我的资产目录的子文件夹中,并且只在一个页面上提供该 .coffee 文件。该页面位于命名路由上

match 'myNotifications' => 'user#notifications'

最明显的做法是将.coffee 文件放入assets\javascripts\user\index.js.coffee。但是在阅读了有关资产的文档后,我并不清楚。

我读到了这一行(来自http://guides.rubyonrails.org/asset_pipeline.html):

您应该将控制器独有的任何 JavaScript 或 CSS 放入其中 它们各自的资产文件,因为这些文件可以被加载 对于这些带有 或 。

好的,所以我将页面特定的 js 放在 assets\javascripts\user.js.coffee 中。然后我重新加载了我的主页,Ctrl F5。 user.js 文件仍在主页上加载。用$ -> alert 'ready from users controller'测试;当我加载主页时看到该警报。

Rails 是否有办法让每页的咖啡脚本文件仅随该页面提供?我读错手册了吗?在 assets 文件夹中是否有一个地方可以放置 .coffee 文件,它们不会随每个页面一起加载?

更新:看起来我可能会have an answer:

有几种方法可以解决这个问题。我们 可以使用 require_directory 而不是 require_tree 因为这只会 加载当前目录而不是子目录中的文件。如果 我们希望对包含的文件进行更多控制,我们可以要求它们 单独而不是包括整个目录。或者我们 可以移动我们想要包含在所有文件中的 JavaScript 文件 页面进入公共子目录。然后我们可以使用 require_tree ./public 仅包含这些文件。

我会在上午试一试。

【问题讨论】:

因为我遇到了同样的问题,所以我决定收集一些我在一个地方遇到的不同的解决方案,并在这里做了一个小写:page-specific-javascript-in-rails-3 【参考方案1】:

这是我用来制作控制器/视图特定咖啡的方法:

application.html.haml:

%body :data =>  :controller => params[:controller], :action => params[:action] 

替代。 application.html.erb

<%= content_tag(:body, :data =>  :controller => params[:controller], :action => params[:action] ) do %>
  ...
<% end %>

application.js.coffee:

$(document).ready ->
  load_javascript($("body").data('controller'),$("body").data('action'))

load_javascript = (controller,action) ->
  $.event.trigger "#controller.load"
  $.event.trigger "#action_#controller.load"

users.js.coffee

$(document).bind 'edit_users.load', (e,obj) =>
  # fire on edit users controller action

$(document).bind 'show_users.load', (e,obj) =>
  # fire on show users controller action

$(document).bind 'users.load', (e,obj) =>
  # fire on all users controller actions

旁注:

这对 PJAX 非常有效,而且您可以在 PJAX 请求上传递带有响应标头的控制器/操作名称,然后基于此触发这些 js 函数。

编辑(2014 年 3 月 4 日): 此解决方案在使用 turbolinks.js 时仍然有效。

【讨论】:

技术不错。不知何故,比起咖啡,我更喜欢常规的 jQuery/JavaScript。太抽象了。【参考方案2】:

您可能只想使用以页面标记为条件的逻辑,而不是只将文件包含在一个页面上。见my answer to a related question。这样一来,您的用户就不必为特定页面发出额外的&lt;script&gt; 请求。

如果有 很多 特定于该页面的逻辑(例如,10K+ 缩小),那么是的,将其拆分出来。正如您在编辑问题时所建议的那样:不要在 javascripts 目录的根目录下执行 require_tree .,而是创建一个名为 global 的子目录并将 application.js 的顶部从

require_tree .

require_tree global

然后将特定页面的 CoffeeScript 文件放在根 javascripts 目录中,并在该页面的模板中使用 javascript_include_tag 调用指向它。

【讨论】:

我开始看到一个大 js 文件的逻辑。这篇文章说,拥有许多 js 和 css 文件会对加载造成重大影响:rubyrobot.org/article/5-tips-for-faster-loading-web-sites 对。正如我所说,拆分它的好处是,如果该特定页面有大量 JS,您不希望人们在加载您的主页时必须下载它。第三种选择是使用异步 JS 加载器,以便访问您主页的人首先加载他们需要的脚本,然后在页面加载后加载其余所有脚本,这样当他们访问您的其他页面时,它们就会被缓存。 我使用的是 Rails 3.2,它要求我将 require_tree 目录列为相对路径,所以我使用了“require_tree ./global”,一切就绪。【参考方案3】:

在您的视图模板中包含 javascript 标记,例如 show.html.haml

- content_for :javascripts do
  = javascript_include_tag 'folder/coffee_file_name'

【讨论】:

以上是关于我应该如何只在一页上包含一个咖啡脚本文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何管理一页上的许多查询?

如何在 Drupal 的一页上显示 2 个包含 2 种内容类型的表格?

如何在一页上放置多个画布js动画。 (创建js)

轮播控制按钮仅在一页上有效

Plotly:如何使用plotly-dash在一页上创建“输入文本”并在第二页或选项卡上输出(图形)?

如何在一页上切换多个 tabSlideOUT 选项卡