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

时间:2011-12-05 23:15:40

标签: javascript ruby-on-rails coffeescript asset-pipeline

rails资产管道存在问题,但是连接所有JS,缩小它并为远期过期标题提供服务的好处很难被忽视。

我的rails应用程序中的很多JS都是针对单个操作的。例如,我们有一个复杂的页面供员工输入客户订单。

pre rails 3.1,我在一个独特的JS文件中有特定于操作的代码,该文件仅在需要时加载。现在我所有的JS都在服务。在需要时只运行订单输入JS的最佳方法是什么?

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

这是一个来自订单输入代码的coffeespcript片段,这个模式在大约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

2 个答案:

答案 0 :(得分:2)

我喜欢将特定于页面的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程序员,但我正在学习这种语言...

答案 1 :(得分:0)

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

//= require_tree .

如果你把它拿出来,它只会包含你特别需要的文件。如果您指定文件夹的名称(而不是.),那么您可以在其中放置要“自动包含”的文件。您可以在Rails Guides中详细了解相关信息。例如,您的application.js文件可能如下所示:

//= require jquery_ujs
//= require main

然后,您可以拥有一个order_entry.js文件,该文件只包含您想要的代码。当然,您可以使用与以前相同的方式链接到这些:

application.js

<%= javascript_include_tag "application" %>

适用于您的新order_entry.js

<%= javascript_include_tag "order_entry" %>