使用 Rails 资产管道时选择性运行 javascript 的最佳方法是什么?

发布于 2024-12-19 19:15:33 字数 663 浏览 3 评论 0原文

Rails 资产管道有其问题,但是连接所有 JS、缩小它并为其提供远期过期标头的好处是很难忽视的。

我的 Rails 应用程序中的许多 JS 都特定于单个操作。例如,我们有一个复杂的页面供员工输入客户订单。

在 Rails 3.1 之前,我将特定于操作的代码放在一个不同的 JS 文件中,仅在需要时才加载。现在我所有的JS都一直在服务。仅在需要时运行订单输入 JS 的最佳方法是什么?

目前我正在检查订单输入 DOM 元素,但这意味着 DOMready 上将运行许多不必要的函数。

下面是订单输入代码中的一段 CoffeeScript 片段,该模式在大约 20 个文件中重复出现。有更好的办法吗?

$ ->
  window.app.draft = new app.DraftOrder()

@module 'app', ->
  class @DraftOrder
    constructor: ->
      @items = $('table.draft-items tr')
      return if @items.size() == 0
      @initEvents()
      @move_first()
    initEvents: ->
      # foo
    otherMethod: ->
      # bar

The rails asset pipeline has it's issues, but the benefits of concatenating all my JS, minifying it and serving it with far-future expires headers are hard to ignore.

Lots of the JS in my rails app is specific to a single action. For example, we have a complex page for staff to enter customer orders.

pre rails 3.1, I had the action-specific code in a distinct JS file that was only loaded when needed. Now all my JS is served all the time. What's the best way to only run the order-entry JS when it's needed?

Currently I'm checking for the order-entry DOM elements, but that means there'll be lots of unnecessary functions running on DOMready.

Here's a snippet of coffeespcript from the order-entry code, and this pattern is repeated in about 20 files. Is there a better way?

$ ->
  window.app.draft = new app.DraftOrder()

@module 'app', ->
  class @DraftOrder
    constructor: ->
      @items = $('table.draft-items tr')
      return if @items.size() == 0
      @initEvents()
      @move_first()
    initEvents: ->
      # foo
    otherMethod: ->
      # bar

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

记忆で 2024-12-26 19:15:33

我喜欢将页面特定的 JS 封装在闭包中,并在应用程序模板中插入代码,以便我有选择地执行它。

因此,“事件”控制器的页面特定 js 可能如下所示:

events = {
  onload: function() {
    // put any page-specific onload code here
  },
  someOtherRoutine: function() {
  }
}

在我的应用程序模板 (application.html.erb) 中,我添加:

<%= javascript_tag do %>
  window.controller_name = <%= params[:controller] %>;
  window.action_name = <%= params[:action] %>;
<% end%>

然后,在 application.js 中(假设您使用 jQuery):

$(function() {
  if(controller_name === 'events'){
    events.onload();
  }
  else if(controller_name === 'anothercontroller'){
    anothercontroller.onload();
  }

  // put any global onload functionality here...
});

这具有额外的优点为所有页面特定的 JS 提供一种穷人的命名空间。

可能有一种更惯用的rails/javascript 方法可以做到这一点;我主要不是 JS 程序员,但我正在学习非常喜欢这门语言......

I like to wrap my page-specific JS in a closure, and insert code in my application template that lets me selectively execute it.

so, my page-specific js for an "Events" controller might look like:

events = {
  onload: function() {
    // put any page-specific onload code here
  },
  someOtherRoutine: function() {
  }
}

in my application template (application.html.erb), I add:

<%= javascript_tag do %>
  window.controller_name = <%= params[:controller] %>;
  window.action_name = <%= params[:action] %>;
<% end%>

then, in application.js (assuming you use jQuery):

$(function() {
  if(controller_name === 'events'){
    events.onload();
  }
  else if(controller_name === 'anothercontroller'){
    anothercontroller.onload();
  }

  // put any global onload functionality here...
});

This has the additional advantage of giving a sort of poor-man's namespacing to all of your page-specific JS.

There's probably a more idiomatic rails/javascript way to do this; I'm not primarily a JS programmer but I am learning to like the language quite a bit...

清浅ˋ旧时光 2024-12-26 19:15:33

它仅包含您的所有 javascript 文件,因为您的 application.js 文件中有此行:

//= require_tree .

如果您将其删除,它将仅包含您特别需要的文件。如果您指定文件夹的名称(而不是 .),那么您可以在其中放置要“自动包含”的文件。您可以在Rails 指南中了解更多相关信息。例如,您的 application.js 文件可能如下所示:

//= require jquery_ujs
//= require main

然后,您可能有一个 order_entry.js 文件,其中只包含您想要的代码。当然,您可以像以前一样链接到这些:

对于 application.js

<%= javascript_include_tag "application" %>

对于新的 order_entry.js

<%= javascript_include_tag "order_entry" %>

It is including all of your javascript files only because you have this line in your application.js file:

//= require_tree .

If you take that out, it will only include the files that you specifically require. If you specify the name of a folder (rather than .), then you can have a spot where you put files that you want to be 'auto-included'. You can read more about this in the Rails Guides. For example, your application.js file could look like this:

//= require jquery_ujs
//= require main

Then, you could have an order_entry.js file that just has the code you want in it. Of course, you link to these the same way you used to:

For application.js:

<%= javascript_include_tag "application" %>

For your new order_entry.js:

<%= javascript_include_tag "order_entry" %>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文