[javascript] Rails 3.1을 사용하면 “페이지 특정”JavaScript 코드를 어디에 배치합니까?

이해하기 위해 모든 JavaScript가 1 파일로 병합됩니다. Rails는 매니페스트 파일 //= require_tree .의 맨 아래에 추가 할 때 기본적으로이 작업을 수행 application.js합니다.

이것은 실제 생명을 구하는 것처럼 들리지만 페이지 별 JavaScript 코드에 대해서는 약간 걱정이됩니다. 이 코드는 모든 페이지에서 실행됩니까? 마지막으로 원하는 것은 모든 객체가 1 페이지에서만 필요할 때 모든 페이지에 대해 인스턴스화되는 것입니다.

또한 충돌하는 코드가있을 가능성이 있습니까?

아니면 script페이지 하단에 페이지의 자바 스크립트 코드를 실행하는 메소드를 호출 하는 작은 태그를 넣습니까?

더 이상 require.js가 필요하지 않습니까?

감사

편집 : 나는 모든 대답을 주셔서 감사합니다 … 그리고 그들이 실제로 문제를 겪고 있다고 생각하지 않습니다. 그들 중 일부는 스타일링에 관한 것이며 관련이없는 것 같습니다 … 그리고 다른 사람들은 javascript_include_tag내가 알고있는 … (분명히 …) 언급 하지만 Rails 3.1 방식은 모든 것을 마무리하는 것 같습니다. 각 페이지의 맨 아래에 개별 JavaScript를로드하는 대신 JavaScript를 1 개의 파일로로드하십시오.

내가 얻을 수있는 가장 좋은 해결책은 특정 기능 divids 또는 classes 로 태그로 묶는 것입니다. 자바 스크립트 코드에서, 당신은 단지 확인 경우 id또는 class페이지에 있고,이 경우, 당신은 그것과 관련된 자바 스크립트 코드를 실행합니다. 이렇게하면 동적 요소가 페이지에 없으면 JavaScript 코드는 application.jsSprockets에 의해 패키지 된 대규모 파일 에 포함되어 있어도 실행되지 않습니다 .

위의 솔루션은 100 페이지 중 8 페이지에 검색 상자가 포함되어 있으면 해당 8 페이지에서만 검색 상자가 실행된다는 이점이 있습니다. 또한 사이트의 8 개 페이지에 동일한 코드를 포함하지 않아도됩니다. 실제로 사이트에 수동 스크립트 태그를 다시 포함시킬 필요가 없습니다.

이것이 내 질문에 대한 실제 답변이라고 생각합니다.



답변

Asset Pipeline 문서는 컨트롤러 별 JS를 수행하는 방법을 제안합니다.

예를 들어, a ProjectsController가 생성되면에 새 파일이 app/assets/javascripts/projects.js.coffee있고에 다른 파일이 있습니다 app/assets/stylesheets/projects.css.scss. 이 파일은 다음 단지 같은 라인이 컨트롤러를로드 할 수있는 당신은, 각각의 자산 파일 내부의 컨트롤러에 자바 스크립트 나 CSS 독특한 하나를 넣어해야 <%= javascript_include_tag params[:controller] %>하거나 <%= stylesheet_link_tag params[:controller] %>.

링크 : asset_pipeline


답변

페이지 별 js의 경우 Garber-Irish 솔루션을 사용할 수 있습니다 .

따라서 Rails javascripts 폴더는 자동차와 사용자의 두 컨트롤러에서 다음과 같이 보일 수 있습니다.

javascripts/
├── application.js
├── init.js
├── markup_based_js_execution
├── cars
   ├── init .js
   ├── index.js
   └── ...
└── users
    └── ...

그리고 자바 스크립트는 다음과 같습니다

// application.js

//= 
//= require init.js
//= require_tree cars
//= require_tree users

// init.js

SITENAME = new Object();
SITENAME.cars = new Object;
SITENAME.users = new Object;

SITENAME.common.init = function (){
  // Your js code for all pages here
}

// cars/init.js

SITENAME.cars.init = function (){
  // Your js code for the cars controller here
}

// cars/index.js

SITENAME.cars.index = function (){
  // Your js code for the index method of the cars controller
}

markup_based_js_execution에는 UTIL 객체 및 DOM 준비 UTIL.init 실행 코드가 포함됩니다.

그리고 이것을 레이아웃 파일에 넣는 것을 잊지 마십시오 :

<body data-controller="<%= controller_name %>" data-action="<%= action_name %>">

또한 data-*더 나은 페이지 별 CSS를 위해 속성 대신 클래스를 사용하는 것이 좋습니다 . Jason Garber가 언급했듯이 페이지 특정 CSS 선택기는 실제로 어색해질 수 있습니다 ( data-*속성 을 사용할 때 )

이것이 도움이되기를 바랍니다.


답변

귀하가 본인의 질문에 답변 한 것으로 나타 났지만 여기에 다른 옵션이 있습니다.

기본적으로, 당신은 가정

//= require_tree .

필요합니다. 그렇지 않습니다. 자유롭게 제거하십시오. 현재 응용 프로그램에서 3.1.x로 처음으로 정직하게 작업하는 세 가지 다른 최상위 JS 파일을 만들었습니다. 내 application.js파일 만

//= require jquery
//= require jquery_ujs
//= require_directory .
//= require_directory ./api
//= require_directory ./admin

이런 식으로, 내가 필요로하는 것만 포함하는 자체 최상위 JS 파일을 사용하여 서브 디렉토리를 작성할 수 있습니다.

열쇠는 다음과 같습니다.

  1. 당신은 제거 할 수 있습니다 require_tree레일은 당신이 만드는 가정을 변경할 수 있습니다 –
  2. 이름에는 특별한 것이 없습니다 application.js. assets/javascript서브 디렉토리의 모든 파일 에는 프리 프로세서 지시문이 포함될 수 있습니다.//=

희망이 ClosureCowboy의 답변에 도움이되고 세부 사항을 추가합니다.

수잘


답변

다른 옵션 : 페이지 또는 모델 별 파일을 작성하기 위해 assets/javascripts/폴더 내에 디렉토리를 작성할 수 있습니다 .

assets/javascripts/global/
assets/javascripts/cupcakes
assets/javascripts/something_else_specific

기본 application.js매니페스트 파일은에서 파일을로드하도록 구성 할 수 있습니다 global/. 특정 페이지 또는 페이지 그룹은 자신의 특정 디렉토리에서 파일을로드하는 자체 매니페스트를 가질 수 있습니다. 스프로킷은로드 된 파일을 application.js페이지 특정 파일과 자동으로 결합 하여이 솔루션이 작동하도록합니다.

이 기술도 사용할 수 있습니다 style_sheets/.


답변

모든 답변에 감사드립니다 … 그리고 그들이 실제로 문제를 겪고 있다고 생각하지 않습니다. 그들 중 일부는 스타일링에 관한 것이고 관련이없는 것 같습니다 … 그리고 다른 사람들은 javascript_include_tag내가 알고있는 … (분명히 …) 언급 하지만 Rails 3.1 방식은 모든 것을 마무리하는 것 같습니다. 각 페이지 하단에 개별 자바 스크립트를로드하지 않고 자바 스크립트를 1 개의 파일로로드합니다.

내가 얻을 수있는 가장 좋은 해결책은 특정 기능 divids 또는 classes 로 태그로 묶는 것입니다. 자바 스크립트 코드에서. 그럼 그냥 확인 경우 id또는 class페이지에 있고,이 경우, 당신은 그것과 관련된 자바 스크립트 코드를 실행합니다. 이렇게하면 동적 요소가 페이지에 없으면 application.jsSprockets에 의해 패키지 된 대규모 파일 에 포함되어 있어도 자바 스크립트 코드가 실행되지 않습니다 .

위의 솔루션은 100 페이지 중 8 페이지에 검색 상자가 포함되어 있으면 해당 8 페이지에서만 검색 상자가 실행된다는 이점이 있습니다. 또한 사이트의 8 개 페이지에 동일한 코드를 포함하지 않아도됩니다. 실제로 데이터를 미리로드하는 경우를 제외하고는 사이트에 수동 스크립트 태그를 다시 포함 할 필요가 없습니다.

이것이 내 질문에 대한 실제 답변이라고 생각합니다.


답변

이 파티에 조금 늦게 온다는 것을 알고 있지만 최근에 사용한 솔루션을 사용하고 싶었습니다. 그러나 먼저 언급하겠습니다 …

The Rails 3.1 / 3.2 Way (아니요, 싫어요)

참조 : http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline

나는이 답변에 완전성을 기하기 위해 다음을 포함시키고 있으며, 그것은 해결책이 아니기 때문에 …별로 신경 쓰지 않지만.

“Rails Way”는이 질문의 원래 작성자가 요청한대로 뷰 지향적이 아니라 컨트롤러 중심의 솔루션입니다. 해당 컨트롤러의 이름을 딴 컨트롤러 특정 JS 파일이 있습니다. 이러한 모든 파일은 기본적으로 application.js에 지시문이 필요하지 않은 폴더 트리에 배치됩니다.

컨트롤러 별 코드를 포함하기 위해 다음이 뷰에 추가됩니다.

<%= javascript_include_tag params[:controller] %>

나는이 솔루션을 싫어하지만 거기에 있으며 빠릅니다. 아마도 “people-index.js”및 “people-show.js”와 같은 파일을 호출 한 다음 "#{params[:controller]}-index"뷰 지향 솔루션을 얻는 데 사용할 수 있습니다. 다시 말하지만, 빠른 수정이지만 나와 잘 어울리지 않습니다.

내 데이터 속성 방식

미친 짓이라고 부르지 만 배포 할 때 모든 JS를 컴파일하고 application.js로 축소하기를 원합니다. 나는이 작은 꼬마 파일을 모든 곳에 포함시켜야한다는 것을 기억하고 싶지 않습니다.

모든 JS를 하나의 압축 된 브라우저 캐시 파일에로드합니다. 내 application.js의 특정 부분을 페이지에서 실행 해야하는 경우 Rails가 아니라 HTML에서 알려줍니다.

JS를 특정 요소 ID에 잠 그거나 마커 클래스로 HTML을 버리기보다는이라는 사용자 정의 데이터 속성을 사용합니다 data-jstags.

<input name="search" data-jstag="auto-suggest hint" />

각 페이지 에서 DOM을로드 할 때 코드를 실행하기 위해 선호하는 JS 라이브러리 메소드를 여기에 삽입하십시오 . 이 부트 스트랩 코드는 다음 작업을 수행합니다.

  1. 로 표시된 DOM의 모든 요소를 ​​반복 data-jstag
  2. 각 요소에 대해 속성 값을 공백으로 분할하여 태그 문자열 배열을 만듭니다.
  3. 각 태그 문자열에 대해 해시에서 해당 태그에 대한 조회를 수행하십시오.
  4. 일치하는 키가 발견되면 해당 키와 연관된 기능을 실행하여 요소를 매개 변수로 전달하십시오.

내 application.js 어딘가에 다음을 정의했다고 가정 해보십시오.

function my_autosuggest_init(element) {
  /* Add events to watch input and make suggestions... */
}

function my_hint_init(element) {
  /* Add events to show a hint on change/blur when blank... */
  /* Yes, I know HTML 5 can do this natively with attributes. */
}

var JSTags = {
  'auto-suggest': my_autosuggest_init,
  'hint': my_hint_init
};

부트 스트랩 이벤트는 검색 입력에 대해 my_autosuggest_initmy_hint_init기능 을 적용하여 입력하는 동안 제안 목록을 표시하는 입력으로 변환하고 입력이 비어 있고 초점이 맞지 않을 때 일종의 입력 힌트를 제공합니다.

일부 요소에 태그가 지정되어 있지 않으면 data-jstag="auto-suggest"자동 제안 코드가 실행되지 않습니다. 그러나 항상 페이지에 필요로하는 시간 동안 application.js에 항상 캐시되고 축소되어 캐시됩니다.

태그가 지정된 JS 함수에 추가 매개 변수를 전달해야하는 경우 창의성을 적용해야합니다. 데이터 매개 변수 속성을 추가하거나 일종의 매개 변수 구문을 찾거나 하이브리드 방식을 사용하십시오.

컨트롤러 고유의 복잡한 워크 플로우가 있더라도 lib 폴더에 파일을 만들고 application.js에 압축하여 ‘new-thing-wizard’와 같은 태그를 지정하면됩니다. 부트 스트랩이 해당 태그에 도달하면 멋진 멋진 마법사가 인스턴스화되어 실행됩니다. 필요할 때 해당 컨트롤러의보기에 대해 실행되지만 컨트롤러에 연결되지는 않습니다. 실제로 마법사를 올바르게 코딩하면보기에 모든 구성 데이터를 제공 할 수 있으므로 나중에 필요한 다른 컨트롤러에 대해 마법사를 다시 사용할 수 있습니다.

어쨌든, 이것은 지금 당장 페이지 특정 JS를 구현 한 방법이며, 간단한 사이트 디자인과 더 복잡하고 풍부한 응용 프로그램 모두에게 도움이되었습니다. 여기에 제시 한 두 가지 방법 중 하나 인 내 방식이나 Rails 방식 중 하나가 앞으로이 질문을 겪는 사람에게 도움이되기를 바랍니다.


답변

이것은 오래 전에 받아 들여졌지만이 답변 중 일부와 Rails 3 이상에 대한 경험을 바탕으로 내 솔루션을 생각해 냈습니다.

자산 파이프 라인이 달콤합니다. 사용해.

먼저 application.js파일에서 제거//= require_tree.

그런 다음 application_controller.rb도우미 메소드를 작성 하십시오 .

helper_method :javascript_include_view_js //Or something similar

def javascript_include_view_js
    if FileTest.exists? "app/assets/javascripts/"+params[:controller]+"/"+params[:action]+".js.erb"
        return '<script src="/assets/'+params[:controller]+'/'+params[:action]+'.js.erb" type="text/javascript"></script>'
    end
end

그런 다음 application.html.erb레이아웃 파일에서 기존 자바 스크립트 포함 중 도우미 앞에 접두사를 추가하여 새 도우미를 추가하십시오 raw.

<head>
    <title>Your Application</title>
    <%= stylesheet_link_tag "application", :media => "all" %>
    <%= javascript_include_tag "application" %>
    <%= raw javascript_include_view_js %>
</head>

Voila, 이제 레일의 다른 곳에서 사용하는 것과 동일한 파일 구조를 사용하여보기 별 자바 스크립트를 쉽게 만들 수 있습니다. 파일을 간단하게 붙이십시오 app/assets/:namespace/:controller/action.js.erb!

다른 사람을 돕는 희망!