在Rails 3应用程序中添加页面特定JavaScript的最佳方法?

2020/10/29 17:03 · javascript ·  · 0评论

Rails 3具有一些不引人注目的JavaScript,这非常酷。

但是我想知道最好的方法是为特定页面包含其他JavaScript。

例如,我以前可能做过的地方:

<%= f.radio_button :rating, 'positive', :onclick => "$('some_div').show();" %>

我们现在可以使用类似的方法使其变得不引人注目

<%= f.radio_button :rating, 'positive' %>

# then in some other file
$('user_rating_positive').click(function() {
  $('some_div').show();
}

所以我想我的问题是在哪里/如何包含该JavaScript?我不想填写application.js文件,因为此JavaScript仅适用于该视图。我应该以某种方式为每个页面包含一个自定义JavaScript文件,还是将其粘贴在标题所要查找的实例变量中?

我想做的是将每个视图的Javascript包含在一个content_for :head块中,然后yield将其包含到您的应用程序布局中。例如

如果很短,则:

<% content_for :head do %>
  <script type="text/javascript">
    $(function() {
      $('user_rating_positve').click(function() {
        $('some_div').show();
      }
    });
  </script>
<% end %>

或者,如果更长,则:

<% content_for :head do %>
  <script type="text/javascript">
    <%= render :partial => "my_view_javascript"
  </script>
<% end %>

然后,在您的布局文件中

<head>
  ...
  <%= yield :head %>
</head>

如果您只想在页面上包含javascript,则当然可以将其内联地包含在页面中,但是,如果您想对javascript进行分组并利用资产管道,缩小的js等优势,则可以这样做并拥有额外的资源通过将js分为仅适用于网站的某些控制器/视图/部分的组来组合并仅加载到特定页面上的js资产。

将资产中的js移动到文件夹中,每个文件夹都有一个单独的清单文件,因此,如果您有一个仅在后端使用的admin js库,则可以执行以下操作:

  • 资产

    • JavaScripts

      • 管理员

        • ... js
      • admin.js(用于管理组的清单)
      • application.js(适用于应用程序全局组的清单)
      • 全球

        • ... js

在现有的application.js中

//= require jquery
//= require jquery_ujs
//= require_tree ./global // requires all js files in global folder

在新的admin.js清单文件中

//= require_tree ./admin // requires all js files in admin folder

通过编辑config / production.rb确保此新的js清单已加载

config.assets.precompile += %w( admin.js )

Then adjust your page layout so that you can include some extra js for the page head:

<%= content_for :header %>   

Then in views where you want to include this specific js group (as well as the normal application group) and/or any page-specific js, css etc:

<% content_for :header do %>
  <%= javascript_include_tag 'admin' %>  
<% end %>

You can of course do the same thing with css and group it in a similar way for applying only to certain areas of the site.

这些答案帮助了我很多!如果有人想要更多...

  1. 如果您希望对JavaScript进行预编译,则需要将它们放入清单中。但是,如果您需要每个javascript文件,application.js.coffee那么每次您导航到另一个页面时,所有javacsripts都将被加载,而实现特定于页面的javascript的目的将被打败。

因此,您需要创建自己的清单文件(例如speciifc.js),该清单文件将需要所有页面特定的javascript文件。另外,require_treeapplication.js

app / assets / javascripts / application.js

//= require jquery
//= require jquery_ujs
//= require_tree ./global

app / assets / javascripts / specific.js

//= require_tree ./specific

然后,environments/production.rb使用config选项将此清单添加到预编译列表中,

config.assets.precompile += %w( specific.js )

做完了!所有应始终加载共享javascript都将放在app/assets/javascripts/global文件夹中,而页面专用javascript会放在中app/assets/javascripts/specific您可以简单地从视图中调用特定于页面的javascript,例如

<%= javascript_include_tag "specific/whatever.js" %> //.js是可选的。

这足够了,但是我也想利用它javascript_include_tag params[:controller]当您创建控制器时,会app/assets/javascripts像提到的其他人一样生成关联的coffeescript文件确实有特定于控制器的javascript,仅当用户到达特定的控制器视图时才加载。

所以我创建了另一个清单 controller-specific.js

app / assets / javascripts / controller-specific.js

//= require_directory .

这将包括与控制器关联的所有自动生成的咖啡脚本。另外,您需要将其添加到预编译列表中。

config.assets.precompile += %w( specific.js controller-specific.js )

我更喜欢以下...

在您的application_helper.rb文件中

def include_javascript (file)
    s = " <script type=\"text/javascript\">" + render(:file => file) + "</script>"
    content_for(:head, raw(s))
end

然后在您的特定视图中(在此示例中为app / views / books / index.html.erb)

<% include_javascript 'books/index.js' %>

...似乎为我工作。

If you don't want to use the asset pipeline or the complex work arounds to get that necessary page specific javascript (I sympathise), the simplest and most robust way, which achieves the same as the answers above but with less code is just to use:

<%= javascript_include_tag "my_javascipt_file" %>

Note: this does require one more http request per include tag than the answers which use content_for :head

看一下pluggable_js gem。您可能会发现此解决方案更易于使用。

我的理解是,资产管道旨在通过将所有js合并到一个(最小化)文件中来减少页面加载时间。尽管从表面上看这似乎令人反感,但实际上它是流行语言(例如C和Ruby)中已经存在的功能。诸如“ include”标签之类的东西旨在防止文件的多次包含,并帮助程序员组织其代码。当您使用C编写和编译程序时,所有代码都存在于正在运行的程序的每个部分中,但是仅在使用该代码时才将方法加载到内存中。从某种意义上说,已编译程序不包含任何保证代码完全模块化的内容。通过以这种方式编写程序,我们使代码模块化,并且操作系统仅将给定位置所需的对象和方法加载到内存中。甚至还有“方法特定的包含”之类的东西吗?如果您的Rails应用程序很安静,这实际上就是您要的。

如果您编写JavaScript来增强页面上HTML元素的行为,则这些功能在设计上是“特定于页面的”。如果您以某种方式编写了一些复杂的代码,无论其上下文如何,该代码都将执行,则无论如何都应考虑将该代码绑定到html元素(您可以使用body标签,如Garber-Irish方法所述)。如果一个函数有条件地执行,则性能可能会比所有这些额外的脚本标记小。

我正在考虑使用Paloma gem,如rails apps项目中所述然后,您可以通过在paloma回调中包含特定于页面的功能,来使您的javascript特定于页面:

Paloma.callbacks['users']['new'] = function(params){
    // This will only run after executing users/new action
    alert('Hello New Sexy User');
}; 

您使用滑轨,所以我知道您喜欢宝石:)

您不应该在资产管道之外加载JS或CSS文件,因为您会失去使Rails如此出色的重要功能。而且您不需要其他宝石。我相信使用尽可能少的宝石,这里没有必要使用宝石。

您想要的就是所谓的“控制器特定的Javascript”(“操作特定的Javascript包含在底部”)。这使您可以为特定的CONTROLLER加载特定的JavaScript文件。尝试将Javascript连接到View是一种。向后,并且不遵循MVC设计模式,您希望将其与Controller或Controller内部的动作相关联。

不幸的是,无论出于何种原因,Rails开发人员都决定默认情况下,每个页面都将加载资产目录中的每个JS文件。为什么他们决定这样做而不是默认情况下启用“特定于控制器的Javascript”,我永远不会知道。这是通过application.js文件完成的,该文件默认包含以下代码行:

//= require_tree .

这称为指令这就是链轮用来加载asset / javascripts目录中的每个JS文件的方式。默认情况下,链轮会自动加载application.js和application.css,而require_tree指令将加载其各自目录中的每个JS和Coffee文件。

注意:当使用脚手架时(如果您不使用脚手架,现在是开始的好时机),Rails会自动为该脚手架的控制器为您生成一个咖啡文件。如果您希望它生成标准的JS文件而不是咖啡文件,请删除Gemfile中默认启用咖啡宝石,然后脚手架将创建JS文件。

好的,启用“特定于控制器的Javascript”的第一步是从application.js文件中删除require_tree代码,或者如果仍然需要全局JS文件,则将其更改为asset / javascripts目录中的文件夹。IE浏览器:

//= require_tree ./global

第2步:进入config / initializers / assets.rb文件,并添加以下内容:

%w( controllerone controllertwo controllerthree ).each do |controller|
  Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.css"]
end

插入所需的控制器名称。

第3步:用此替换您的application.html.erb文件中的javascript_include_tag(注意params [:controller]部分:

<%= javascript_include_tag 'application', params[:controller], 'data-turbolinks-track': 'reload' %>

重新启动服务器和中提琴!用脚手架生成的JS文件现在仅在调用该控制器时加载。

是否需要在控制器IE / articles / new中的特定ACTION上加载特定的JS文件改为这样做:

application.html.erb

<%= javascript_include_tag "#{controller_name}/#{action_name}" if AppName::Application.assets.find_asset("#{controller_name}/#{action_name}") %>

config / initializers / assets.rb

config.assets.precompile += %w(*/*)

然后在资产/ javascripts文件夹中添加一个与您的控制器同名的新文件夹,并将与您的动作同名的js文件放入其中。然后将其加载到该特定操作上。

好的,也许这就像有史以来最糟糕的工作,但是我创建了一个控制器方法,该方法只是呈现出.js文件

控制者

def get_script
   render :file => 'app/assessts/javascripts/' + params[:name] + '.js'
end
def get_page
   @script = '/' + params[:script_name] + '.js?body=1'
   render page
end

视图

%script{:src => @script, :type => "text/javascript"}

如果由于某种原因我们不想这样做,请告诉我。

添加JS的首选方法是在页脚中,因此您可以这样做:

show.html.erb:

<% content_for :footer_js do %>
   This content will show up in the footer section
<% end %>

layouts / application.html.erb

<%= yield :footer_js %>
本文地址:http://javascript.askforanswer.com/zairails-3yingyongchengxuzhongtianjiayemiantedingjavascriptdezuijiafangfa.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!