Rails 3 앱에서 페이지 특정 JavaScript를 추가하는 가장 좋은 방법은?
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 파일을 포함시켜야합니까, 아니면 헤더가 찾는 인스턴스 변수에 고정해야합니까?
내가 좋아하는 것은 뷰 당 자바 스크립트를 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>
한 페이지에만 자바 스크립트를 포함하려면 페이지 인라인에 자바 스크립트를 포함시킬 수 있지만 자바 스크립트를 그룹화하고 자산 파이프 라인, 축소 된 js 등을 활용하려는 경우 추가 할 수 있으며 추가 할 수 있습니다 js 자산을 사이트의 특정 컨트롤러 /보기 / 섹션에만 적용되는 그룹으로 분할하여 특정 페이지에만 결합되고로드되는 js 자산.
자산의 js를 각각 별도의 매니페스트 파일과 함께 폴더로 이동하므로 백엔드에서만 사용되는 admin js 라이브러리가있는 경우 다음을 수행 할 수 있습니다.
- 자산
- 자바 스크립트
- 관리자
- ... 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 manifest를로드하십시오.
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.
I prefer the following...
In your application_helper.rb file
def include_javascript (file)
s = " <script type=\"text/javascript\">" + render(:file => file) + "</script>"
content_for(:head, raw(s))
end
and then in your particular view (app/views/books/index.html.erb in this example)
<% include_javascript 'books/index.js' %>
... seems to work for me.
These answers helped me a ton! If anyone wants a little more...
- You need to put javascripts into manifests if you want them precompiled. However, if you require every javascript file from
application.js.coffee
then all the javacsripts will be loaded every time you navigate to a different page, and the purpose of doing page-specific javascripts will be defeated.
Therefore, you need to create your own manifest file (e.g. speciifc.js
) that will require all the page-specific javascript files. Also, modify require_tree
from application.js
app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require_tree ./global
app/assets/javascripts/specific.js
//= require_tree ./specific
Then in your environments/production.rb
add this manifest to the precompiled list with the config option,
config.assets.precompile += %w( specific.js )
Done! All the shared javascripts that should always be loaded will be placed in app/assets/javascripts/global
folder, and the page-spcific javascripts in app/assets/javascripts/specific
. You can simply call the page-specific javascripts from the view like
<%= javascript_include_tag "specific/whatever.js" %>
//.js is optional.
This is sufficient, but I wanted to make a use of javascript_include_tag params[:controller]
too. When you create controllers, an associated coffeescript file is generated in app/assets/javascripts
like other people mentioned. There are truly controller-specific javascripts, which are loaded only when the user reaches the specific controller view.
So I created another manifest controller-specific.js
app/assets/javascripts/controller-specific.js
//= require_directory .
This will include all the automatically-generated coffeescripts associated with controllers. Also, you need to add it to the precompiled list.
config.assets.precompile += %w( specific.js controller-specific.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
Take a look at pluggable_js gem. You may find this solution easier to use.
My understanding is that the asset pipeline is meant to decrease page load-time by mashing all your js together into one (minified) file. While this may seem repugnant on the surface, it is actually a feature that already exists in popular languages like C and Ruby. Things like "include" tags are meant to prevent multiple inclusion of a file, and to help programmers organize their code. When you write and compile a program in C, all that code is present in every part of your running program, but methods are only loaded into memory when that code is being used. In a sense, a compiled program does not include anything to guarantee that the code is nicely modular. We make the code modular by writing our programs that way, and the operating system only loads into memory the objects and methods we need for a given locality. Is there even such a thing as "method-specific inclusion"? If your rails app is restful, this is essentially what you are asking for.
If you write your javascript so that it augments the behaviour of HTML elements on the page, then those functions are 'page-specific' by design. If there is some complicated code that you wrote in such a way that it will execute regardless of its context, maybe consider binding that code to an html element anyway (you could use the body tag, as described in the Garber-Irish method). If a function executes conditionally, the performance will probably be smaller than all those extra script tags.
I am thinking of using the paloma gem, as described in the rails apps project. Then you can make your javascript page-specific by including page-specific functions in a paloma callback:
Paloma.callbacks['users']['new'] = function(params){
// This will only run after executing users/new action
alert('Hello New Sexy User');
};
You use rails, so I know you love gems :)
You shouldn't be loading your JS or CSS files outside of the asset pipeline because you lose out on important features that make Rails so great. And you don't need another gem. I believe in using as few gems as possible, and using a gem isn't necessary here.
What you want is known as "Controller Specific Javascript" ("Action Specific Javascript is included at the bottom). This allows you to load a specific JavaScript file for a specific CONTROLLER. Trying to connect your Javascript to a View is kind of... backwards and doesn't follow the MVC design pattern. You want to associate it with your Controllers or actions inside your Controllers.
Unfortunately, for whatever reason, Rails devs decided that by default, every page will load every JS file located in your assets directory. Why they decided to do this instead of enabling "Controller Specific Javascript" by default I will never know. This is done through the application.js file, which includes the following line of code by default:
//= require_tree .
This is known as a directive. It's what sprockets uses to load every JS file in the assets/javascripts directory. By default, sprockets automatically loads application.js and application.css, and the require_tree directive loads every JS and Coffee file in their respective directories.
NOTE: When you scaffold (if you aren't scaffolding, now is a good time to start), Rails automatically generates a coffee file for you, for that scaffold's controller. If you want it to generate a standard JS file instead of a coffee file, then remove the coffee gem that is enabled by default in your Gemfile, and your scaffold will create JS files instead.
Ok, so the first step to enabling "Controller Specific Javascript" is to remove the require_tree code from your application.js file, OR change it to a folder within your assets/javascripts directory if you still need global JS files. I.E.:
//= require_tree ./global
Step 2: Go into your config/initializers/assets.rb file, and add the following:
%w( controllerone controllertwo controllerthree ).each do |controller|
Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.css"]
end
Insert the Controller names that you want.
Step 3: Replace the javascript_include_tag in your application.html.erb file with this (note the params[:controller] part:
<%= javascript_include_tag 'application', params[:controller], 'data-turbolinks-track': 'reload' %>
Restart your server and viola! The JS file that was generated with your scaffold will now only load when that controller is called.
Need to load a specific JS file on a specific ACTION in your controller, I.E. /articles/new ? Do this instead:
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(*/*)
Then add a new folder with the same name as you controller in your assets/javascripts folder and put your js file with the same name as your action inside. It will then load it on that specific action.
Ok so maybe this is like the worst work around ever but i creat a controller method that just rendered out the .js file
Controller
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
View
%script{:src => @script, :type => "text/javascript"}
if for some reason we don't want to do this then let me know.
The preferred way to add JS is in footer, so you can do this way:
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 %>
'development' 카테고리의 다른 글
볼륨을 사용하여 고정 된 postgres 데이터베이스에 데이터를 유지하는 방법 (0) | 2020.06.05 |
---|---|
CMake 출력을 'bin'디렉토리로 만들려면 어떻게합니까? (0) | 2020.06.05 |
WordPress에서 현재 페이지 이름을 얻는 방법은 무엇입니까? (0) | 2020.06.05 |
CSS에서 id와 class의 차이점과 사용시기 (0) | 2020.06.05 |
std :: string에 문자를 추가하는 방법은 무엇입니까? (0) | 2020.06.05 |