从覆盖 rails 引擎资产的文件中获取 javascript

Requiring javascript from files overriding assets of a rails engine

我写了一个 rails 引擎,希望能够在安装它的任何应用程序中自定义它。

[引擎/]app/assets/my_engine/application.js:

//= require jquery
//= require ./engine_specific
//= require ./engine_customization

[APP/]app/assets/my_engine/engine_customization.js:

//= require selectize

$(document).ready(function () {
    $('select').selectize();
});

这会导致js错误(selectize不是一个函数)

我尝试要求其他 files/libs 和 none 由链轮加载。

不确定我是不是做错了什么,或者这实际上是链轮中的错误。

编辑:

[引擎/]app/views/layouts/my_engine/application.html.haml:

!!!
%html
  %head
    %title My Engine
    = stylesheet_link_tag    "my_engine/application", media: "all"
    = javascript_include_tag "my_engine/application"
    = csrf_meta_tags
  %body
    = render 'my_engine/shared/header'
    #content
      #wrapper
        = yield

默认情况下,只有应用的 application.js 清单由 sprockets 预编译。 所以你有两个选择:

A)

要求my_engine/application.js内 应用程序的 js 清单

//app/assets/javascripts/application.js

//= require myengine/application.js 

B) 将 my_engine/application.js 添加到 assets.precompile 数组,然后将其包含在 javascript_include_tag

 #engine.rb

 initializer "myengine.precompile" do |app|
   app.config.assets.precompile += %w(application.js)
 end

 #views/foos/show.html.erb

 javascript_include_tag 'myengine/application.js'

事实证明,混合引擎和应用程序布局相当棘手,所以我采用了不同的方法。一个也 gems 喜欢的设计似乎使用:

我在我的 gem 中编写了生成器,将视图复制到应用程序,而其他生成器则为必须指定应用程序布局的控制器创建装饰器。但它有一些注意事项:如果您的布局包含使用路径助手(即导航栏)的视图,您需要在助手前加上前缀 "main_app."。所以 blog_post_path 变成 main_app.blog_post_path 并且 polymorphic_path([:edit, :admin, @resource]) 变成 main_app.polymorphic_path... 等等。

另一件事是您的应用程序控制器可能定义的实例变量或 before_filters,布局呈现的视图需要这些变量。这些你也需要在控制器装饰器中定义。