提问人:David N. Welton 提问时间:12/13/2011 最后编辑:CommunityDavid N. Welton 更新时间:4/26/2013 访问量:1240
Rails 3.1 中特定于页面的 javascript 文件
Page specific javascript files in Rails 3.1
问:
我一直在做这方面的研究:
使用 Rails 3.1,你把你的“页面特定”javascript 代码放在哪里?
但我还没有看到一个满意的答案,这也让我怀疑我是否做错了什么。
这是我的心智模型:对于不同的观点,我会有不同的
$(document).ready(....)
块,显然引用了该页面非常特定的元素。我不想通过为每个页面加载该代码并以某种方式试图弄清楚如何仅在特定页面上执行它来污染事物;这似乎很丑陋。
诚然,我的直觉没有得到任何初步实验的支持,理想的做法是:
- 从 application.js 加载应用程序范围的代码。
- 从 assets/controller_name/shared 之类的内容加载共享控制器代码.js
- 从 assets/controller_name/show 等位置加载特定于视图的代码.js
从我的头顶上掉下来。帮助程序将在第一次运行时检查文件是否存在,如果存在,则对其进行javascript_include。
与“让我们把整个事情包装在一个大粘球中并全部发送”的方法相比,这也许存在一些性能问题,但似乎是划分代码的更好方法。
然而,如上所述,我感觉我错过了一些东西。$(document).ready on a page on a page is a bad idea that is a bad ideas?($(document).ready on a page on a page based on the per page is a bad idea?这是否应该只是在模板中并从应用程序.js调用特定于页面的JS位?上面的链接文章得出了这个结论,但我不喜欢我脑海中浮现的一个巨大的 $(文档).ready 充斥着 if this, if that, if the other thing.
答:
你建议的是声音,但不是 rails 3.1 方式。
他们说将 JS 分成许多文件,但对用户来说却是一个完整的整体。这样可以提高性能和可扩展性,因此,如果最后的大块泥浆不是那么大,这是一件好事。实际上,3 个 http 请求的性能比 1 个 http 请求差。
因此,您已经划分了代码,因为您有不同的 Coffeescript 文件,它们具有不同的作用域。
要加载到您的应用程序中,只需标准化一种初始化单段代码的方法,例如调用“myapp.users.init()”方法。
您甚至可以使用帮助程序自动执行代码,因此它对控制器是透明的。
评论
背景
(为什么要使用 Asset Pipeline?
Rails 资产管道背后的一个基本前提是这样的想法,即最好预先加载一个站点的所有 JS 和 CSS,然后无限期地缓存它们(至少在站点更新之前)。借助 Asset Pipeline,您可以相对自动地执行此操作,同时仍以逻辑方式组织 JS 和 CSS src 文件。
这当然会带来前期加载成本,并有望节省加载单个文件的额外往返时间。如果这个前提不合适,那么资产管道可能不适合您。
问题的核心
好的,所以我们想将所有 JS 合并到一个文件中,以便更有效地加载它。仅仅因为我们要加载所有的 JS 并不意味着我们要运行所有的 JS。
在复杂的 Web 应用程序的现实中,您可能会拥有许多特定于页面的功能,当用户未查看相应的页面时,您不希望花费资源来执行这些功能。我们需要的是一个统一的策略,用于仅执行适用于当前页面的大型单体 JS 文件部分。
拯救公约
我不知道有官方的 Rails 策略来解决这个问题,但有一些很好的解决方案可以建立并利用一个好的约定(这让事情感觉很“Railsy”)。一般的想法是将所有特定于页面的 JS 代码定义为对象文字,然后在加载时仅运行与当前页面相关的代码。
有关如何组织和有条件地执行 JS 代码的具体策略,请参阅@welldan97对此问题的回答:
使用 Rails 3.1,您将“特定于页面”的 javascript 代码放在哪里?
这又是基于 Jason Garber 的这篇文章:
http://viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution
评论