रेल 3.1 का उपयोग करते हुए, आप अपना "पृष्ठ विशिष्ट" जावास्क्रिप्ट कोड कहां रखते हैं?


388

मेरी समझ से, आपके सभी जावास्क्रिप्ट 1 फ़ाइल में विलय हो जाते हैं। जब यह //= require_tree .आपकी application.jsप्रकट फ़ाइल के निचले भाग में जुड़ जाता है, तो रेल डिफ़ॉल्ट रूप से ऐसा करती है ।

यह एक वास्तविक जीवन रक्षक की तरह लगता है, लेकिन मैं पृष्ठ-विशिष्ट जावास्क्रिप्ट कोड के बारे में थोड़ा चिंतित हूं। क्या इस कोड को हर पृष्ठ पर निष्पादित किया जाता है? आखिरी बात यह है कि मैं चाहता हूं कि मेरी सभी वस्तुओं को हर पृष्ठ के लिए तत्काल किया जाए जब वे केवल 1 पृष्ठ पर हों।

इसके अलावा, कोड के लिए कोई संभावना नहीं है जो क्लैश भी करता है?

या क्या आप scriptपृष्ठ के निचले भाग में एक छोटा सा टैग लगाते हैं जो सिर्फ एक विधि में कॉल करता है जो पृष्ठ के लिए जावास्क्रिप्ट कोड निष्पादित करता है?

क्या अब आपको आवश्यकता नहीं है।

धन्यवाद

संपादित करें : मैं सभी उत्तरों की सराहना करता हूं ... और मुझे नहीं लगता कि वे वास्तव में समस्या में हैं। उनमें से कुछ स्टाइल के बारे में हैं और संबंधित नहीं लगते हैं ... और अन्य बस उल्लेख करते हैं javascript_include_tag... जो मुझे पता है कि मौजूद है (जाहिर है ...) लेकिन यह प्रतीत होगा कि रेल 3.1 रास्ता आगे बढ़ रहा है सभी को लपेटने के लिए प्रत्येक पृष्ठ के नीचे अलग-अलग जावास्क्रिप्ट लोड करने के बजाय 1 जावास्क्रिप्ट में आपकी फ़ाइल।

सबसे अच्छा समाधान मैं साथ आ सकता है एस या एस के divसाथ टैग में कुछ सुविधाओं को लपेटने के लिए । जावास्क्रिप्ट कोड में, आप सिर्फ यह देखते हैं कि क्या पेज पर है या नहीं , और अगर यह है, तो आप जावास्क्रिप्ट कोड चलाते हैं जो इसके साथ जुड़ा हुआ है। इस तरह से अगर डायनामिक तत्व पेज पर नहीं है, तो जावास्क्रिप्ट कोड नहीं चलता है - भले ही इसे ट्रॉकेट्स द्वारा पैक की गई भारी फाइल में शामिल किया गया हो।idclassidclassapplication.js

मेरे उपरोक्त समाधान का यह लाभ है कि यदि खोज पृष्ठ को 100 पृष्ठों में से 8 पर शामिल किया जाता है, तो यह केवल उन 8 पृष्ठों पर चलेगा। आपको साइट पर पृष्ठों के 8 पर समान कोड शामिल नहीं करना होगा। वास्तव में, आपको कभी भी अपनी साइट पर मैनुअल स्क्रिप्ट टैग को कभी भी फिर से शामिल नहीं करना पड़ेगा।

मुझे लगता है कि यह मेरे प्रश्न का वास्तविक उत्तर है।


11
"रेलगाड़ी का 3.1 रास्ता आगे बढ़ना है, प्रत्येक पेज के नीचे अलग-अलग जावास्क्रिप्ट लोड करने के बजाय अपनी सभी जावास्क्रिप्ट को 1 फ़ाइल में लपेटना है।" - केवल रेल कोर टीम ही है और हमेशा रही है, यह जानकर बहुत बुरा लगा कि कैसे जावास्क्रिप्ट का प्रबंधन करने के लिए। छोटी फाइलें आम तौर पर बेहतर होती हैं (मेरी टिप्पणियों को कहीं और देखें)। जब यह जावास्क्रिप्ट की बात आती है, तो रेल मार्ग शायद ही कभी सही तरीका होता है (संपत्ति पाइपलाइन को छोड़कर, जो गधा को मारता है, और कॉफीस्क्रिप्ट का प्रोत्साहन)।
मार्नेन लाइबो-कोसर

तो आप अपने पृष्ठ-विशिष्ट js फ़ाइलों को हर पृष्ठ पर शामिल करेंगे? मुझे लगता है कि यह एक बेकार है, मैं क्लोजर कॉवॉय के जवाब से अधिक सहमत हूं।
gerky

1
क्या आपके पास इस प्रश्न के स्वीकृत उत्तर पर एक नज़र है? stackoverflow.com/questions/6571753/…
rassom

1
@DutGRIFF दूसरे शब्दों में: नहीं, इस मामले में (या कम से कम, सब कुछ मत डालिए) रेल की चीजों को करना सबसे अच्छा नहीं है application.js, और वास्तव में आपके द्वारा दिया गया संदर्भ यह बताता है कि ऐसा क्यों है: डाउनलोड करना जेएस निष्पादन प्रक्रिया का सबसे धीमा हिस्सा। कई छोटी फाइलें एक से एक बड़ी हैं। अपवित्र रेल के लोगों को यह पता ही नहीं लगता कि, उनकी सिफारिशें उन सिद्धांतों के साथ असंगत हैं, जिनका वे पालन करने का प्रयास कर रहे हैं, और इसलिए उनकी सिफारिशों को गंभीरता से नहीं लिया जाना चाहिए।
मार्नेन लाईबो-कोसर

1
@DutGRIFF नहीं, एक बड़ी जेएस फाइल आम तौर पर एक बार कैश होने के बाद भी अच्छी बात नहीं होगी। मेरी टिप्पणियों को इस पृष्ठ पर अन्यत्र देखें: छोटी फाइलें विशिष्ट पृष्ठों को बेहतर तरीके से लक्षित कर सकती हैं, और उन्हें बारीक रूप से देखा जा सकता है। मैं एक बड़ी फ़ाइल के लिए किसी भी अच्छा उपयोग के मामले नहीं दिख रहा है जब तक कि वहाँ कोई पृष्ठ-विशिष्ट कोड है सब पर
मार्नैन लाइबो-कोसर

जवाबों:


157

एसेट पाइप लाइन डॉक्स नियंत्रक-विशिष्ट जेएस कैसे करें:

उदाहरण के लिए, यदि कोई ProjectsControllerउत्पन्न होता है, तो एक नई फ़ाइल होगी app/assets/javascripts/projects.js.coffeeऔर दूसरी पर app/assets/stylesheets/projects.css.scss। आपको किसी भी जावास्क्रिप्ट या सीएसएस को अपनी संबंधित परिसंपत्ति फ़ाइलों के अंदर एक नियंत्रक के लिए अद्वितीय रखना चाहिए, क्योंकि ये फाइलें केवल इन नियंत्रकों जैसे कि <%= javascript_include_tag params[:controller] %>या के लिए लोड की जा सकती हैं <%= stylesheet_link_tag params[:controller] %>

इससे लिंक करें: wealth_pipeline


50
यह इसे करने का सबसे सुरुचिपूर्ण तरीका है। लेकिन इसके अलावा, आपको लाइन को हटाने की आवश्यकता होगी // = requirement_tree। आवेदन से।
जेसी टॉफी

2
मैं इस पद्धति से पूरी तरह सहमत हूं। अन्य तरीके बहुत ही भद्दे लगते हैं और फिर भी एक विशाल js फ़ाइल को लोड करते हैं। जिस प्रोजेक्ट im पर काम किया जा रहा है, उसमें लगभग 2mb का JS फाइल / प्लगइन्स आदि AFTER / संयुक्त रूप से जोड़ा जा रहा है।
बिल गैरिसन

2
मैं रेल के लिए काफी नया हूं, लेकिन मुझे लगता है कि यह डिफ़ॉल्ट व्यवहार होना चाहिए।
रॉस हैम्ब्रिक

12
कार्रवाई के विशिष्ट नियंत्रण के लिए मेरे पास मेरे लेआउट में है, क्योंकि प्रत्येक नियंत्रक के लिए प्रत्येक कार्रवाई में विशिष्ट जेएस नहीं है। page_specific_js = "#{params[:controller]}_#{params[:action]}"और फिर; javascript_include_tag page_specific_js if Rails.application.assets.find_asset page_specific_js
सुजीमची

2
क्या नियंत्रक विशिष्ट कार्य अभी भी खनन किए जाते हैं? क्या वे एकल js फ़ाइल में जोड़े जाते हैं जो sprockets द्वारा बनाई गई हैं, या इसने संपत्ति फ़ाइलों के लिए कई अनुरोधों को जन्म दिया है?
जेसन

77

पृष्ठ-विशिष्ट js के लिए आप गार्बर-आयरिश समाधान का उपयोग कर सकते हैं

तो आपके रेल 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-*बेहतर पृष्ठ-विशिष्ट सीएसएस के लिए, विशेषताओं के बजाय कक्षाओं का उपयोग करना बेहतर है। जैसा कि जेसन गार्बर ने उल्लेख किया है: पृष्ठ-विशिष्ट सीएसएस चयनकर्ता वास्तव में अजीब हो सकते हैं (जब आप उपयोग करते हैंdata-* विशेषताओं का हैं)

उम्मीद है इससे आपको मदद मिलेगी।


4
क्या होगा यदि आपको उपयोगकर्ता नियंत्रक में सभी कार्यों के लिए उपलब्ध चर की आवश्यकता है, लेकिन अन्य नियंत्रकों में उपलब्ध नहीं है? क्या इस पद्धति में कुछ समस्याएँ नहीं हैं?
tybro0103

@ tybro0103, मुझे लगता है कि इस व्यवहार को लागू करने के लिए आप window.varForOneController='val'इस नियंत्रक इनिट फ़ंक्शन में कुछ लिखना चाहेंगे । इसके अलावा गॉन मणि यहां मदद कर सकते हैं ( github.com/gazay/gon )। अन्य कामगार हो सकते हैं।
वेल्डेन 97

1
@ welldan97 डाउनवोटिंग आपके स्पष्टीकरण के लिए नहीं - जो उत्कृष्ट है - लेकिन क्योंकि गार्बर-आयरिश संरचना बुराई है। यह आपके सभी जेएस को हर पेज पर लोड करता है, और चीजों को छांटने के लिए <शरीर> तत्व पर कक्षाओं और आईडी पर निर्भर करता है। यह DOM से लड़ने का एक निश्चित संकेत है: सामान्य परिस्थितियों में <body> तत्व को किसी वर्ग या ID की आवश्यकता नहीं होनी चाहिए, क्योंकि दस्तावेज़ में कभी एक ही होता है। ऐसा करने का उचित तरीका केवल //= require_tree .पृष्ठ-विशिष्ट जावास्क्रिप्ट को निकालना और उपयोग करना है। यदि आप सक्रिय रूप से ऐसा नहीं करने की कोशिश कर रहे हैं, तो आप बुरे अभ्यास के लिए प्रयास कर रहे हैं।
मार्नेन लाईबो-कोसर

2
@ MarnenLaibow-Koser व्यक्तिगत रूप से मेरा मानना ​​है कि हर पृष्ठ पर सभी js को लोड करना सबसे अधिक परियोजनाओं के लिए अच्छा है जब आप सभी js को एक फ़ाइल में जोड़ते हैं और इसे कम करते हैं। मेरा मानना ​​है कि यह कुल मिलाकर उपयोगकर्ता के लिए तेजी से काम करता है। कम से कम इसके और अधिक संघर्ष की तरह एक जेएस फ़ाइल बनाम कई (यानी स्टैकओवरफ्लो को देखें। विजय / 555696/… )। इसके अलावा शरीर पर कक्षाओं और आईडी का उपयोग करने में कुछ भी बुरा नहीं है अगर यह कोड को सरल बनाता है और आपके लिए काम करता है। Modernizr ( modernizr.com ) ऐसा करता है, और कुछ अन्य परिवाद भी।
वेल्लादन 97

2
@ MarnenLaibow-Koser रेल परिसंपत्ति पाइपलाइन, मेरे लिए, संकलन के साथ तुलना के लिए एक अच्छे उम्मीदवार की तरह लगता है। एक प्रोग्रामर ने अपनी जावास्क्रिप्ट को अच्छे डिकॉउंड किए गए मॉड्यूल में लिखता है, और फिर इसे एक साथ, मिनिफाइज्ड और सर्व किया जाता है। जिस तरह संकलित भाषाओं के मामले में, हमेशा ऐसे प्रोग्रामर होंगे जो सोचते हैं कि वे संकलक से एक कदम आगे हैं ... लेकिन मुझे लगता है कि यह शायद ही सच है।
जिग्गी

65

मैं देखता हूं कि आपने अपने प्रश्न का उत्तर दिया है, लेकिन यहां एक और विकल्प है:

असल में, आप यह धारणा बना रहे हैं कि

//= require_tree .

आवश्यक है। यह। इसे हटाने के लिए स्वतंत्र महसूस करें। मेरे वर्तमान आवेदन में, मैं 3.1.x ईमानदारी से कर रहा हूं, मैंने तीन अलग-अलग शीर्ष स्तर की जेएस फाइलें बनाई हैं। मेरी application.jsफाइल में ही है

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

इस तरह, मैं अपने स्वयं के शीर्ष स्तर जेएस फाइलों के साथ उपनिर्देशिका बना सकता हूं, जिसमें केवल वही शामिल हो सकता है जो मुझे चाहिए।

चाबियाँ हैं:

  1. आप हटा सकते हैं require_tree- रेल आपको इसकी मान्यताओं को बदलने देता है
  2. नाम के बारे में कुछ खास नहीं है application.js- assets/javascriptउपनिर्देशिका में कोई भी फ़ाइल के साथ पूर्व-प्रोसेसर निर्देश शामिल हो सकते हैं//=

आशा है कि कुछ विवरणों को बंद करने और जोड़ने के लिए क्लोजकॉबॉय के उत्तर में मदद करता है।

Sujal


8
+1 यह मेरे जैसे नौसिखिया के लिए जानना बहुत अच्छा है। अगर मैं कर सकता तो मैं इसे +2 देता।
jhhorn424

5
@sujal बिल्कुल रेल कोर टीम abysmal JavaScript प्रबंधन के लिए कुख्यात है। बेझिझक उनके सुझावों को नजरअंदाज करें और सिर्फ एसेट पाइपलाइन के अच्छे हिस्सों का इस्तेमाल करें । :)
मार्नेन लाईबो-कोसर

1
इस सलाह के लिए बहुत बहुत धन्यवाद। मेरे पास मेरे ऐप के मॉड्यूल के आधार पर कई "शीर्ष-स्तरीय" जेएस फाइलें नहीं हैं। अच्छा काम करता है।
elsurudo

1
यहाँ मेरे लिए +1 महत्वपूर्ण बात यह है कि आप की जगह ले सकता है //= require_tree .के साथ //= require_directory .ताकि आप वे कहाँ हैं और पेज विशिष्ट फ़ाइलों के लिए नई निर्देशिका बनाने के सभी मौजूदा फ़ाइलों रख सकते हैं।
zelanix

41

एक अन्य विकल्प: पेज- या मॉडल-विशिष्ट फ़ाइलें बनाने के लिए, आप अपने assets/javascripts/फ़ोल्डर के अंदर निर्देशिका बना सकते हैं ।

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

आपकी मुख्य application.jsमेनिफ़ेस्ट फ़ाइल को इसकी फ़ाइलों को लोड करने के लिए कॉन्फ़िगर किया जा सकता है global/। विशिष्ट पृष्ठों या पृष्ठों के समूह के अपने स्वयं के मैनिफ़ेस्ट हो सकते हैं जो अपनी विशिष्ट निर्देशिकाओं से फ़ाइलें लोड करते हैं। Sprockets स्वचालित रूप से लोड की गई फ़ाइलों को संयोजित करेगाapplication.js से आपके पृष्ठ-विशिष्ट फ़ाइलों के साथ , जो इस समाधान को काम करने की अनुमति देता है।

इस तकनीक का उपयोग भी किया जा सकता है style_sheets/


13
आपने मुझे अब कपकेक लालसा कर दिया है .. खतरनाक!
चक बर्जरॉन

मुझे वास्तव में यह समाधान पसंद है। मेरे पास एकमात्र समस्या यह है कि उन अतिरिक्त अभिव्यक्तियाँ संकुचित / बदसूरत नहीं हैं। वे हालांकि ठीक से संकलित हैं। क्या कोई हल है या मुझे कुछ याद आ रहा है?
क्लस्ट

1
इसका मतलब यह है कि ब्राउज़र एक जेएस फ़ाइल लोड करता है, जो कि वैश्विक + पृष्ठ विशिष्ट फ़ाइल का एक संयोजन है?
लूलाला

यदि आप उपलब्ध हैं तो क्या आप मेरे प्रश्न पर एक नज़र डाल सकते हैं? stackoverflow.com/questions/17055213/…
मैक्सिमस एस

1
@ मुझे विश्वास है कि यह वह उत्तर है जिसकी आप तलाश कर रहे हैं: guide.rubyonrails.org/asset_pipeline.html#precompiling-assets
FrontierPsycho

23

मैं सभी उत्तरों की सराहना करता हूं ... और मुझे नहीं लगता कि वे वास्तव में समस्या पर हैं। उनमें से कुछ स्टाइल के बारे में हैं और संबंधित नहीं लगते ... और अन्य बस उल्लेख करते हैंjavascript_include_tag ... जो मुझे पता है कि मौजूद है (जाहिर है ...) लेकिन यह प्रतीत होगा कि रेल 3.1 रास्ता आगे बढ़ रहा है सभी को लपेटने के लिए प्रत्येक पेज के नीचे अलग-अलग जावास्क्रिप्ट लोड करने के बजाय आपकी जावास्क्रिप्ट 1 फ़ाइल में।

सबसे अच्छा समाधान मैं साथ आ सकता है एस या एस के divसाथ टैग में कुछ सुविधाओं को लपेटने के लिए । जावास्क्रिप्ट कोड में। तब आप बस जाँचते हैं कि पृष्ठ पर है या नहीं , और यदि यह है, तो आप जावास्क्रिप्ट कोड चलाते हैं जो इसके साथ जुड़ा हुआ है। इस तरह से अगर डायनेमिक एलिमेंट पेज पर नहीं है, तो जावास्क्रिप्ट कोड नहीं चलता है - भले ही इसे Sprockets द्वारा पैक की गई भारी फाइल में शामिल किया गया हो।idclassidclassapplication.js

मेरे उपरोक्त समाधान का यह लाभ है कि यदि खोज पृष्ठ को 100 पृष्ठों में से 8 पर शामिल किया जाता है, तो यह केवल उन 8 पृष्ठों पर चलेगा। आपको साइट पर पृष्ठों के 8 पर समान कोड शामिल नहीं करना होगा। वास्तव में, आपको कभी भी अपनी साइट पर मैनुअल स्क्रिप्ट टैग को कभी भी शामिल नहीं करना पड़ेगा - शायद डेटा को प्रीलोड करने के अलावा।

मुझे लगता है कि यह मेरे प्रश्न का वास्तविक उत्तर है।


लेकिन आप वास्तव में उन मैनुअल <script>टैग चाहते हैं । हां, कक्षाएं और आईडी उत्तर का हिस्सा हैं, लेकिन यह उपयोगकर्ता को जावास्क्रिप्ट को लोड करने के लिए कोई मतलब नहीं है कि उस विशेष पृष्ठ की आवश्यकता नहीं है।
मार्नेन लाईबो-कोसर

4
@ MarnenLaibow-Koser प्रत्येक अद्वितीय पृष्ठ पर मैनुअल स्क्रिप्ट टैग नहीं जोड़ने का कारण यह है कि आपको हर पृष्ठ दृश्य पर उस स्क्रिप्ट सामग्री को डाउनलोड करना होगा। यदि आप एसेट पाइपलाइन का उपयोग करके सभी जावास्क्रिप्ट को application.js में पैकेज करने में सक्षम हैं, तो उपयोगकर्ता उन लिपियों को एक बार ही डाउनलोड करता है, और बाद के सभी पेज लोड पर कैश से application.js को खींचता है
jakeonrails

@jakeonrails "प्रत्येक अद्वितीय पृष्ठ पर मैन्युअल स्क्रिप्ट टैग न जोड़ने का कारण यह है कि आपको प्रत्येक पृष्ठ दृश्य पर वह स्क्रिप्ट सामग्री डाउनलोड करनी होगी" - गलत है। स्क्रिप्ट को एक बार डाउनलोड किया जाएगा, फिर आगे के अनुरोध पर ब्राउज़र के कैश से प्राप्त किया जाएगा। "यदि आप एसेट पाइपलाइन का उपयोग करके सभी जावास्क्रिप्ट को एप्लिकेशन में जमा कर सकते हैं, तो उपयोगकर्ता उन लिपियों को केवल एक बार डाउनलोड करता है" - लेकिन, बहुत सारे अनावश्यक कोड की कीमत पर। यदि आप अपने जेएस को एक बड़े के बजाय कई छोटी फाइलों में ढाँक सकते हैं, तो आपको बिना अनावश्यक कोड के कैशिंग लाभ मिलते हैं।
मर्नेन लाईबो-कोसर

1
@ MarnenLaibow-Koser मुझे लगता है कि यह कहना बेहतर होगा कि यदि आप एक स्क्रिप्ट में सब कुछ पैकेज करते हैं, तो आपके उपयोगकर्ता को आपकी साइट के किसी भी पृष्ठ के लिए केवल 1 स्क्रिप्ट डाउनलोड करना होगा। यदि आपके पास अपने ऐप के विभिन्न हिस्सों के लिए कई स्क्रिप्ट हैं, तो जाहिर है उपयोगकर्ता को एक से अधिक स्क्रिप्ट डाउनलोड करना होगा। दोनों तरीकों को कैश किया जाएगा, लेकिन ज्यादातर मामलों में (छोटे-मध्यम ऐप), एक एप्लिकेशन की सेवा। एक बार डाउनलोड करने के लिए एक समय अधिक कुशल होगा। जेएस की पार्सिंग एक और कहानी हो सकती है, जो आप की सेवा पर निर्भर करती है।
जेकोन्रिल्स

1
@Ziggy इसके अलावा, यदि छोटी फ़ाइल का उपयोग केवल 100 में से 8 पृष्ठों पर किया जाता है, तो कोड को हर समय उपयोगकर्ता के कैश में क्यों बैठना चाहिए? बेहतर है कि वास्तव में उस सामान को छोड़ दें जिसकी जरूरत नहीं है।
मार्नेन लाइबो-कोसर

16

मुझे पता है कि मैं इस पार्टी में थोड़ी देर से आ रहा हूं, लेकिन मैं एक समाधान में फेंकना चाहता था जिसे मैं हाल ही में उपयोग कर रहा हूं। हालाँकि, मुझे पहले उल्लेख ...

रेल 3.1 / 3.2 वे (नहीं, सर। मुझे यह पसंद नहीं है।)

देखें: http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline

मैं इस उत्तर में पूर्णता की खातिर निम्नलिखित शामिल कर रहा हूं, और क्योंकि यह एक अनुचित समाधान नहीं है ... हालांकि मुझे इसकी ज्यादा परवाह नहीं है।

"रेल्स वे" इस प्रश्न के मूल लेखक के रूप में देखने-उन्मुख होने के बजाय एक नियंत्रक-उन्मुख समाधान है। नियंत्रक-विशिष्ट जेएस फाइलें उनके संबंधित नियंत्रकों के नाम पर हैं। इन सभी फ़ाइलों को एक फ़ोल्डर ट्री में रखा जाता है जो कि किसी भी एप्लिकेशन में डिफ़ॉल्ट रूप से शामिल नहीं है। जेएस को निर्देशों की आवश्यकता होती है।

नियंत्रक-विशिष्ट कोड को शामिल करने के लिए, निम्नलिखित को एक दृश्य में जोड़ा जाता है।

<%= javascript_include_tag params[:controller] %>

मैं इस समाधान को खो देता हूं, लेकिन यह वहां है और यह जल्दी है। संभवतः, आप इन फ़ाइलों को "पीपल-इंडेक्स.जेएस" और "पीपल-शो.जेएस" जैसे कुछ कह सकते हैं और फिर कुछ का उपयोग कर सकते हैं जैसे "#{params[:controller]}-index"कि एक दृश्य-उन्मुख समाधान प्राप्त करना। फिर से, जल्दी ठीक, लेकिन यह मेरे साथ अच्छी तरह से नहीं बैठता है।

माई डेटा एट्रीब्यूट वे

मुझे पागल कहो, लेकिन मैं चाहता हूं कि मेरे सभी जेएस को संकलित किया जाए और जब मैं तैनात हूं तो आवेदन में जमा करें। मैं इन छोटे स्ट्रैगलर फ़ाइलों को सभी जगह शामिल करने के लिए याद रखना नहीं चाहता।

मैं अपने सभी जेएस को एक कॉम्पैक्ट, जल्द ही ब्राउजर कैश्ड, फाइल में लोड करता हूं। यदि मेरे आवेदन का एक निश्चित टुकड़ा। Js को एक पृष्ठ पर निकाल दिया जाना चाहिए, तो मैंने HTML को मुझे बताया, न कि रेल को।

अपने जेएस को विशिष्ट तत्व आईडी पर लॉक करने या मार्कर कक्षाओं के साथ अपने HTML को बंद करने के बजाय, मैं एक कस्टम डेटा विशेषता का उपयोग करता हूं data-jstags

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

प्रत्येक पृष्ठ पर, मैं उपयोग करता हूं - पसंदीदा जेएस लाइब्रेरी विधि यहां डालें - जब डोम ने लोड करना समाप्त कर लिया है। यह बूटस्ट्रैपिंग कोड निम्नलिखित क्रियाएं करता है:

  1. DOM में सभी तत्वों से अधिक के साथ चिह्नित करें data-jstag
  2. प्रत्येक तत्व के लिए, विशेषता मान को अंतरिक्ष पर विभाजित करें, टैग स्ट्रिंग्स की एक सरणी बनाएं।
  3. प्रत्येक टैग स्ट्रिंग के लिए, उस टैग के लिए Hash में लुकअप करें।
  4. यदि एक मिलान कुंजी पाई जाती है, तो उस फ़ंक्शन को चलाएं जो इसके साथ जुड़ा हुआ है, तत्व को पैरामीटर के रूप में पास कर रहा है।

तो कहते हैं कि मेरे आवेदन में कहीं न कहीं निम्नलिखित परिभाषित है।

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_initऔर my_hint_initफ़ंक्शंस को लागू करने जा रहा है , इसे एक इनपुट में बदल दिया जाता है जो उपयोगकर्ता के प्रकारों के साथ-साथ सुझावों की एक सूची प्रदर्शित करता है, साथ ही साथ इनपुट के खाली होने और अनफ़ोक किए जाने पर कुछ प्रकार के इनपुट संकेत भी प्रदान करता है।

जब तक कुछ तत्व के साथ टैग नहीं किया जाता है data-jstag="auto-suggest", तब तक ऑटो-सुझाव कोड कभी भी फायर नहीं करता है। हालाँकि, यह हमेशा वहाँ रहता है, छोटा और अंततः मेरे एप्लिकेशन में कैश किया जाता है। उन समय के लिए जो मुझे एक पृष्ठ पर चाहिए।

यदि आपको अपने टैग किए गए जेएस कार्यों के लिए अतिरिक्त पैरामीटर पास करने की आवश्यकता है, तो आपको कुछ रचनात्मकता लागू करनी होगी। या तो डेटा-पैरामिटर विशेषताओं को जोड़ें, कुछ प्रकार के पैरामीटर सिंटैक्स के साथ आएं, या यहां तक ​​कि हाइब्रिड दृष्टिकोण का उपयोग करें।

यहां तक ​​कि अगर मेरे पास कुछ जटिल वर्कफ़्लो हैं जो कंट्रोलर-विशिष्ट लगता है, तो मैं बस इसके लिए एक फ़ाइल अपने लिबास फ़ोल्डर में बनाऊंगा, इसे application.js में पैक करूँगा और इसे 'नई-चीज़-विज़ार्ड' जैसी किसी चीज़ के साथ टैग करूँगा। जब मेरा बूटस्ट्रैप उस टैग को हिट करता है, तो मेरा अच्छा, फैंसी विज़ार्ड त्वरित और चला जाएगा। यह जरूरत पड़ने पर उस नियंत्रक के दृश्य के लिए चलता है, लेकिन अन्यथा नियंत्रक को युग्मित नहीं किया जाता है। वास्तव में, यदि मैं अपने विज़ार्ड को सही कोड देता हूं, तो मैं सभी कॉन्फ़िगरेशन डेटा को विचारों में प्रदान करने में सक्षम हो सकता हूं और इसलिए बाद में किसी भी अन्य नियंत्रक के लिए मेरे विज़ार्ड का उपयोग करने में सक्षम हो सकता हूं, जिसे इसकी आवश्यकता है।

वैसे भी, यह है कि मैं कुछ समय के लिए पृष्ठ विशिष्ट जेएस को कैसे लागू कर रहा हूं, और इसने मुझे सरल साइट डिजाइनों और अधिक जटिल / समृद्ध अनुप्रयोगों के लिए अच्छी तरह से सेवा दी है। उम्मीद है कि मेरे द्वारा प्रस्तुत किए गए दो समाधानों में से एक, मेरा रास्ता या रेल रास्ता, किसी के लिए भी उपयोगी है, जो भविष्य में इस सवाल पर आता है।


6
एक छोटा विवरण: आपके उत्तर में यह धारणा है कि एक बार js ब्राउज़र कैश हो जाने के बाद, इसका कोई प्रभाव नहीं पड़ता है। यह बिल्कुल सच नहीं है। ब्राउज़र वास्तव में डाउनलोड से बचता है, अगर जेएस फ़ाइल ठीक से कैश नहीं है, लेकिन यह अभी भी हर पेज रेंडर पर कोड संकलित करता है। इसलिए, आपको ट्रेडऑफ को संतुलित करना होगा। यदि आपके पास कुल मिलाकर बहुत सारे जेएस हैं, लेकिन प्रति पृष्ठ केवल कुछ का उपयोग किया जाता है, तो आप जेएस को अलग करके पृष्ठ समय में सुधार करने में सक्षम हो सकते हैं।
सुजल

उस संकलन कदम के व्यावहारिक प्रभावों के बारे में अधिक जानकारी के लिए, 37 संकेत देखें कि कैसे pjax ने Basecamp को प्रभावित किया अगला: 37signals.com/svn/posts/…
sujal

यह एक उचित बिंदु है। लेख को पढ़ने और उन परियोजनाओं पर वापस देखने के बाद, जहां मैंने उपरोक्त समाधान का उपयोग किया है, मुझे एहसास है कि मैंने अनिवार्य रूप से एक ही लिखा था "परिवर्तित HTML भेजें" समाधान वे लेख में उल्लेख करते हैं। जेएस के बार-बार संकलन के कारण मेरी परियोजनाओं में कोई समस्या नहीं थी। जब मैं कम "डेस्कटॉप एप्लिकेशन" उन्मुख साइटों पर काम कर रहा हूं, तो संकलन कदम कुछ मुझे ध्यान में रखना होगा।
रयान

2
डाउनवोटिंग के लिए "मुझे पागल कहो, लेकिन मैं चाहता हूं कि मेरे सभी जेएस को संकलित किया जाए और जब मैं तैनात हो तो आवेदन में जमा करें।" आप वास्तव में यह नहीं चाहते हैं, क्योंकि यह उपयोगकर्ता को जावास्क्रिप्ट लोड करता है जिसकी उसे आवश्यकता नहीं है और यह आपके हैंडलर को उन विशेषताओं की तलाश करता है जो वहां होने वाली नहीं हैं। App.js में सब कुछ होने के बावजूद, और रेल निश्चित रूप से इसे आसान बनाती है, लेकिन इसके लिए उचित बात यह है कि जावास्क्रिप्ट को बेहतर ढंग से संशोधित किया जाए।
मार्नेन लाइबो-कोसर

आप एक अलग राय के हकदार हैं ... और तकनीकी रूप से राय के अंतर से नीचे उतरने के हकदार हैं। हालाँकि, कुछ औचित्य देखना अच्छा होगा कि क्यों एक बड़ी और कैश्ड फ़ाइल को संशोधित जेएस को हथियाने के लिए कई HTTP अनुरोधों को मजबूर करने के लिए अवर है। इसके अलावा, आप हैंडलर खोज प्रक्रिया के बारे में गलत हैं। टैग मान खोजे नहीं जाते हैं। केवल एक खोज कभी की जाती है और यह उन सभी तत्वों को खींच लेती है जिनमें डेटा-jstag विशेषता होती है। यह टैग के नाम से नहीं खोजता है, यह सिर्फ उन सभी तत्वों को खोजता है जिनके पास टैग हैं और फिर केवल आवश्यक वस्तुओं को त्वरित करता है।
रयान

7

यह उत्तर दिया गया है और बहुत पहले स्वीकार कर लिया गया है, लेकिन मैं इन उत्तरों में से कुछ के आधार पर अपने स्वयं के समाधान के साथ आया हूं और रेल 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>

वोइला, अब आप आसानी से एक ही फाइल संरचना का उपयोग करके दृश्य-विशिष्ट जावास्क्रिप्ट बना सकते हैं जो आप रेल का उपयोग हर जगह रेल में करते हैं। बस में अपनी फ़ाइलें छड़ी app/assets/:namespace/:controller/action.js.erb!

आशा है कि किसी और की मदद करता है!


1
संपत्ति के प्री-कम होने और <%= raw ... %>404 के बाद वापसी के समय इस समस्या का कारण नहीं होगा?
निशांत

मुझे लगता है कि परिसंपत्ति पाइपलाइन अन-स्वीट है, क्योंकि यह फाइलों का एक गुच्छा बनाता है जिन्हें अक्सर उपयोग नहीं किया जाना चाहिए। इसलिए मेरे लिए परिसंपत्ति पाइपलाइन पर निर्भर होना एक अक्षम प्रणाली पर निर्भरता पैदा कर रहा है।
देबोराह

1
@DeborahSpeece एसेट पाइपलाइन उन फ़ाइलों को कब बनाता है जिनका उपयोग नहीं किया जाना चाहिए? क्या आप require_tree /(खराब) एसेट पाइपलाइन (अच्छा) को भ्रमित कर रहे हैं ?
मार्नेन लाईबो-कोसर

6

आप इस लाइन को अपनी विशिष्ट फ़ाइल (जैसे Application.html.erb) में स्वचालित रूप से नियंत्रक विशिष्ट जावास्क्रिप्ट फ़ाइल (जो कि जब आपने नियंत्रक बनाया था बनाया गया था) लोड करने के लिए जोड़ सकते हैं:

<%= javascript_include_tag params[:controller] %>

आप प्रति-क्रिया आधार में स्क्रिप्ट फ़ाइल को स्वचालित रूप से लोड करने के लिए एक पंक्ति भी जोड़ सकते हैं।

<%= javascript_include_tag params[:controller] + "/" + params[:action] %>

बस अपने पृष्ठ स्क्रिप्ट को नियंत्रक नाम के नाम पर एक उपनिर्देशिका में डालें। इन फ़ाइलों में आप = आवश्यकता के उपयोग से अन्य स्क्रिप्ट शामिल कर सकते हैं। ब्राउजर में 404 फेल होने से बचने के लिए फाइल को शामिल करने के लिए केवल एक सहायक बनाना अच्छा होगा।


6
<%= javascript_include_tag params[:controller] %>

2
ऐसा लगता है कि यह प्रश्न का उत्तर देने में सक्षम हो सकता है। क्या आप कृपया इसका जवाब दे सकते हैं कि वह मांस का जवाब दे?


5

LoadJS मणि एक और विकल्प है:

LoadJS Sprockets द्वारा प्रदान किए गए जादू को खोए बिना एक रेल एप्लिकेशन में पेज-विशिष्ट जावास्क्रिप्ट कोड को लोड करने का एक तरीका प्रदान करता है। आपके सभी जावास्क्रिप्ट कोड एक जावास्क्रिप्ट फ़ाइल में छोटा करके जारी रहेंगे, लेकिन इसके कुछ अंश केवल कुछ पृष्ठों के लिए निष्पादित किए जाएंगे।

https://github.com/guidomb/loadjs


3

फिलिप का जवाब काफी अच्छा है। यहाँ यह काम करने के लिए कोड है:

Application.html.erb में:

<body class="<%=params[:controller].parameterize%>">

आपके नियंत्रक को प्रोजेक्ट्स कहा जाता है, जो उत्पन्न करेगा:

<body class="projects">

फिर परियोजनाओं में।

jQuery ->
  if $('body.projects').length > 0  
     $('h1').click ->
       alert 'you clicked on an h1 in Projects'

डाउनवोटिंग: कोई भी सॉल्यूशन जो किसी भी वर्ग पर है <body>, वह गलत है। मेरी टिप्पणियों को इस पृष्ठ पर अन्यत्र देखें।
मर्नेन लाईबो-कोसर

यह मत करो। यहाँ समस्या यह है कि हर बार जब आप इनमें से किसी एक को जोड़ते हैं, तो आप js का एक और टुकड़ा जोड़ रहे होते हैं, जिसे पेज लोड करने की आवश्यकता होती है। आपकी परियोजना के बढ़ने पर निश्चित रूप से कुछ प्रदर्शन में गिरावट हो सकती है।
ifightcrime

2

जावा स्क्रिप्ट केवल तभी मर्ज किए जाते हैं जब आप उन्हें विलय करने के लिए रेल (स्पोकेट्स, बल्कि) बताते हैं।


बेशक। मुझे लगता है कि मैं पूछता हूं क्योंकि रेल की चूक में फ़ोल्डर में सब कुछ शामिल है ... जिसका अर्थ है कि डेविड आपके लिए ऐसा करने का इरादा रखता है। लेकिन जैसा कि मैंने @rubyprince के लिए अन्य टिप्पणी में कहा, मैं निष्पादन के बारे में अनिश्चित हूं जब यह इस तरह से किया जाता है। मैं सोच रहा हूं कि मुझे अक्षम करना है //= require_tree .?
अग्नि प्रतीक

@FireEmblem हां। require_tree .आमतौर पर एक बुरा विचार है।
मार्नेन लाइबो-कोसर

2

यह है कि मैं कैसे स्टाइल मुद्दे को हल: (Haml बहाना)

%div{:id => "#{params[:controller].parameterize} #{params[:view]}"}
    = yield

इस तरह मैं सभी पृष्ठ विशिष्ट .css.sass फ़ाइलों के साथ शुरू करता हूं :

#post
  /* Controller specific code here */
  &#index
    /* View specific code here */
  &#new
  &#edit
  &#show

इस तरह आप आसानी से किसी भी झड़प से बच सकते हैं। जब यह .js. टोफ़ी फ़ाइलों की बात आती है, तो आप तत्वों को इनिशियलाइज़ कर सकते हैं;

$('#post > #edit') ->
  $('form > h1').css('float', 'right')

आशा है कि इससे कुछ मदद मिली।


1
अंतिम बार फिर से पढ़ें कृपया, जावास्क्रिप्ट के लिए आप स्टाइलशीट के लिए उपयोग की जाने वाली समान संरचना का लाभ उठा सकते हैं, जो कि विशिष्ट कार्यों को देखने के लिए स्टाइलशीट के लिए उपयोग किया जाता है।
ज़ेरावे

फिलिप, $('#post > #edit') ->अमान्य लगता है। आप कैसे एक दायरे में काम करने के लिए jQuery गुंजाइश है?
रेमन तयाग

2
हाल ही में मैंने एप्लिकेशन html.haml में इसे कॉल करके सभी नियंत्रक विशिष्ट जावा स्क्रिप्ट और स्टाइल शीट लोड करना शुरू कर दिया है; = javascript_include_tag "application"और = javascript_include_tag params[:controller]इस तरह से मैं जावास्क्रिप्ट कोड को फ़ाइल के अंदर एक गुंजाइश निर्दिष्ट किए बिना सीमित रख सकता हूं।
ज़ेरेव


2

मैं आपके उत्तर से सहमत हूं, यह देखने के लिए कि क्या चयनकर्ता वहां है, का उपयोग करें:

if ($(selector).length) {
    // Put the function that does not need to be executed every page
}

(वास्तविक समाधान जोड़ने के लिए किसी को नहीं देखा)


2

मुझे ऐसा जवाब नहीं दिखता जो वास्तव में यह सब एक साथ रखता हो और आपके लिए इसे पूरा करता हो। इस प्रकार, मैं डाल करने की कोशिश करेंगे meleyal , sujal (एक ला ClosureCowboy ), के पहले भाग रयान के जवाब है, और यहां तक कि गल का एक तरीका है कि छोटी और स्पष्ट है में Backbone.js के बारे में साहसिक बयान ... सब एक साथ। और, जो जानता है, मैं मार्नेन लाइबो-कोसर की आवश्यकताओं को भी पूरा कर सकता हूं ।

उदाहरण संपादन

परिसंपत्तियाँ / javascripts / application.js

//= require jquery
//= require jquery_ujs
//= require lodash.underscore.min
...


दृश्य / लेआउट / application.html.erb

  ...
  </footer>

  <!-- Javascripts ================================================== -->
  <!-- Placed at the end of the document so the pages load faster -->
  <%= javascript_include_tag "application" %>
  <%= yield :javascript %>

</body>
</html>


views / foo / index.html.erb

...
<% content_for :javascript do %>
  <%= javascript_include_tag params[:controller] %>
<% end %>


एसेट्स / जेवास्क्रिप्शन / foo.js

//= require moment
//= require_tree ./foostuff


एसेट्स / जेवास्क्रिप्शन्स / फोस्टफफ / फूटिस.जेसेकोफी

alert "Hello world!"


संक्षिप्त विवरण

  • निकालें //= require_tree .से application.js और इस सूची में केवल जेएस कि प्रत्येक पृष्ठ के शेयरों।

  • में ऊपर दिखाए गए दो पंक्तियों application.html.erb जहां application.js और अपने पृष्ठ-विशिष्ट जे एस शामिल करने के लिए पृष्ठ को बताना होगा।

  • Index.html.erb में ऊपर दिखाई गई तीन पंक्तियाँ कुछ पृष्ठ-विशिष्ट JS को देखने के लिए आपका दृष्टिकोण बताती हैं और इसे ": जावास्क्रिप्ट" (या जो भी आप इसे नाम देना चाहते हैं) नाम के एक उपज क्षेत्र में शामिल करती हैं। इस उदाहरण में, नियंत्रक "फू" है, इसलिए रेल आवेदन लेआउट में: जावास्क्रिप्ट उपज क्षेत्र में "foo.js" को शामिल करने का प्रयास करेंगे।

  • अपने पृष्ठ-विशिष्ट JS को foo.js (या जो भी नियंत्रक नाम दिया गया है) को सूचीबद्ध करें । सामान्य पुस्तकालयों, एक पेड़, निर्देशिका, जो भी हो, सूची दें।

  • अपने कस्टम पृष्ठ-विशिष्ट JS को किसी ऐसे स्थान पर रखें जहाँ आप इसे अपने अन्य कस्टम JS के अलावा आसानी से संदर्भित कर सकें। इस उदाहरण में, foo.js को फ़ॉस्टोस्टफ ट्री की आवश्यकता होती है, इसलिए अपने कस्टम JS को वहां रखें, जैसे कि foothis.js.coff

  • यहां कोई कठिन नियम नहीं हैं। जरूरत से ज्यादा चीजों को स्थानांतरित करने के लिए स्वतंत्र महसूस करें और यदि आवश्यक हो तो विभिन्न लेआउट में विभिन्न नामों के कई उपज क्षेत्र भी बनाएं। यह सिर्फ एक संभव पहला कदम आगे दिखाता है। (मैं इसे ठीक वैसे ही नहीं करता, जैसे कि हमारे Backbone.js के उपयोग को देखते हुए। मैं फू-ज्स को फोस्टफ के बजाय फू नामक एक फ़ोल्डर में छोड़ना चुन सकता हूं, लेकिन अभी तक यह तय नहीं किया है।)

टिप्पणियाँ

आप सीएसएस और के साथ इसी तरह की बातें कर सकते हैं <%= stylesheet_link_tag params[:controller] %> लेकिन यह सवाल के दायरे से बाहर है।

अगर मैं यहाँ एक शानदार अभ्यास से चूक गया, तो मुझे एक नोट भेजें और मैं किशोरावस्था मनाऊंगा। रेल मेरे लिए काफी नया है और, ईमानदारी से, मैं बहुत प्रभावित नहीं हूँ अब तक अराजकता के साथ यह उद्यम विकास के लिए डिफ़ॉल्ट रूप से लाता है और सभी यातायात औसत रेल कार्यक्रम उत्पन्न करता है।


यह जाने का रास्ता दिखता है, मैं यह देखने जा रहा हूं कि क्या मैं इसे अपने ऐप में लागू कर सकता हूं, विस्तृत उत्तर के लिए धन्यवाद।
martincarlin87

1

मेरे पास एक और समाधान है, जो हालांकि आदिम मेरे लिए ठीक काम करता है और इसे किसी फैंसी चयनात्मक लोडिंग रणनीतियों की आवश्यकता नहीं है। अपने नॉर्नल डॉक्यूमेंट तैयार फंक्शन में रखें, लेकिन उसके बाद यह देखने के लिए कि क्या वह पेज आपके जावास्क्रिप्ट का उद्देश्य है, यह देखने के लिए वर्तमान विंडो स्थान का परीक्षण करें:

$(document).ready(function() {
   if(window.location.pathname.indexOf('/yourpage') != -1) {
          // the javascript you want to execute
   }
}

यह अभी भी सभी js को एक छोटे पैकेज में रेल 3.x द्वारा लोड करने की अनुमति देता है, लेकिन उन पेजों के साथ बहुत अधिक ओवरहेड या कोई विरोध उत्पन्न नहीं करता है, जिसके लिए js इरादा नहीं है।


1

ryguy का उत्तर एक अच्छा उत्तर है, भले ही इसे नकारात्मक अंक भूमि में उतारा गया हो।

खासकर यदि आप बैकबोन जेएस की तरह कुछ का उपयोग कर रहे हैं - प्रत्येक पृष्ठ का अपना बैकबोन दृश्य है। तब एरब फाइल में इनलाइन जावास्क्रिप्ट की एक ही लाइन होती है जो सही बैकबोन व्यू क्लास को फायर करती है। मैं इसे 'गोंद कोड' की एक पंक्ति मानता हूं और इसलिए तथ्य यह है कि इसकी इनलाइन ठीक है। लाभ यह है कि आप अपने "requirement_tree" को रख सकते हैं जो ब्राउज़र को सभी जावास्क्रिप्ट को कैश करने देता है।

show.html.erb में, आपके पास कुछ इस तरह होगा:

<% provide :javascript do %>
  <%= javascript_include_tag do %>
    (new app.views.ProjectsView({el: 'body'})).render();
  <% end %>
<% end do %>

और आपकी लेआउट फ़ाइल में, आपको आवश्यकता होगी:

<%= yield :javascript %>

Downvoting। इनलाइन जावास्क्रिप्ट एक अच्छा विचार नहीं है। यहां तक ​​कि अगर यह गोंद कोड है, तो यह एक बाहरी फ़ाइल में होना चाहिए।
मार्नेन लाइबो-कोसर

1

अपनी सभी कमोड जेएस फाइलों को 'ऐप / एसेट्स / जावास्क्रिप्ट / ग्लोबल' जैसे सब-फोल्डर में ले जाएं, फिर एप्लीकेशन में ।js, //= require_tree .लाइन को संशोधित करें//= require_tree ./global

अब आप अपने नियंत्रक-विशिष्ट JS को 'ऐप / एसेट्स / जावास्क्रिप्ट / रूट' पर रखने के लिए स्वतंत्र हैं और उन्हें संकलित JS में शामिल नहीं किया जाएगा, बस इस्तेमाल किया जा रहा है जब आप उन्हें = javascript_include_tagअपने कंट्रोलर / व्यू पर कॉल करते हैं।


कोई रास्ता नहीं, कि एक पृष्ठ के लिए लोड करने के लिए जावास्क्रिप्ट का एक बोझ है। यह कैश्ड होने पर भी कोई फर्क नहीं पड़ता।
१२:४५ पर जैकटेलिन

1

यद्यपि आपके पास यहां कई उत्तर हैं, मुझे लगता है कि आपका संपादन संभवतः सबसे अच्छा दांव है। एक डिज़ाइन पैटर्न जो हम अपनी टीम में उपयोग करते हैं जो हमें Gitlab से मिला है वह डिस्पैचर पैटर्न है। यह कुछ वैसा ही करता है जैसा आप बात कर रहे हैं, हालांकि पेज का नाम बॉडी टैग में रेल्स द्वारा सेट किया गया है। उदाहरण के लिए, अपनी लेआउट फ़ाइल में, जैसे कुछ शामिल करें (HAML में):

%body{'data-page' => "#{controller}:#{action}" }

उसके बाद केवल एक क्लोजर और एक स्विच स्टेटमेंट आपके dispatcher.js.coffeeफाइल में आपके javascripts फ़ोल्डर में होता है जैसे:

$ ->
  new Dispatcher()

class Dispatcher
  constructor: ->
    page = $('body').attr('data-page')
    switch page
      when 'products:index'
        new Products() 
      when 'users:login'
        new Login()

आपको केवल अलग-अलग फाइलों में (कहने products.js.coffeeया login.js.coffeeउदाहरण के लिए) उन्हें एक कक्षा में संलग्न करना है और फिर उस वर्ग चिन्ह को वैश्वीकरण करना है ताकि आप इसे डिस्पैचर में एक्सेस कर सकें:

class Products
  constructor: ->
    #do stuff
@Products = Products

Gitlab के कई उदाहरण हैं जिनसे आप उत्सुक होने की स्थिति में चारों ओर प्रहार करना चाहते हैं :)


1

पालोमा परियोजना पृष्ठ विशिष्ट जावास्क्रिप्ट कोड के प्रबंधन के लिए दिलचस्प दृष्टिकोण प्रदान करती है।

उनके डॉक्स से उपयोग उदाहरण:

var UsersController = Paloma.controller('Users');

// Executes when Rails User#new is executed.
UsersController.prototype.new = function(){
   alert('Hello Sexy User!' );
};

1

चरण 1। आवश्यकता_ट्री निकालें। अपने application.js और application.css में।

चरण 2। लेआउट फ़ोल्डर में अपना application.html.erb (रेल डिफ़ॉल्ट रूप से) संपादित करें। निम्नलिखित टैग्स में "params [: कंट्रोलर]" जोड़ें।

<%= stylesheet_link_tag    'application', params[:controller], media: 'all', 'data-turbolinks-track' => true %>

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

चरण 3। Config / initializers / आस्तियों में एक फाइल जोड़ें

%w( controller_one controller_two controller_three ).each do |controller|
  Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.js.coffee", "#{controller}.css", "#{controller}.scss"]
end

संदर्भ: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/


जब भी यह सैद्धांतिक रूप से प्रश्न का उत्तर दे सकता है, तो उत्तर के आवश्यक भागों को शामिल करना और संदर्भ के लिए लिंक प्रदान करना बेहतर होगा
भार्गव राव

0

मैंने इसे आज़माया नहीं है, लेकिन ऐसा लगता है कि निम्नलिखित सत्य है:

  • यदि आपके पास एक ऐसी सामग्री है, जो कि जावास्क्रिप्ट है (जैसे कि उसके भीतर वास्तविक जावास्क्रिप्ट के साथ), तो sprockets को इसके बारे में नहीं पता होगा और इस प्रकार यह उसी तरह काम करेगा जैसा अभी करता है।

  • यदि आप किसी फ़ाइल को जावास्क्रिप्ट के बड़े बंडल से बाहर करना चाहते हैं, तो आप config / sprockets.yml फ़ाइल में जाएंगे और तदनुसार source_files को संशोधित करेंगे। उसके बाद, आप बस उन फ़ाइलों को शामिल करेंगे जिन्हें आपने बाहर रखा था, जहां जरूरत थी।


क्या फाइलों को छोड़कर या पृष्ठ पर कस्टम जावास्क्रिप्ट का उपयोग करना "सही तरीका" है? क्या डेविड ने लोगों को इसका उपयोग करने का इरादा दिया है?
आग प्रतीक

@FireEmblem मुझे बहुत परवाह नहीं है कि डेविड क्या इरादा रखता है, क्योंकि मुझे नहीं लगता कि डेविड समझता है कि जावास्क्रिप्ट को ठीक से कैसे व्यवस्थित किया जाए।
मार्नेन लाईबो-कोसर


0

मैंने कुछ उत्तरों को संयुक्त किया:

आवेदन सहायक:

module ApplicationHelper
  def js_page_specific_include
    page_specific_js = params[:controller] + '_' + params[:action]
    if Rails.application.assets.find_asset(page_specific_js).nil?
      javascript_include_tag 'application', 'data-turbolinks-track' => true
    else
      javascript_include_tag 'application', page_specific_js, 'data-turbolinks-track' => true
    end
  end
end

लेआउट / application.html.haml:

 <!DOCTYPE html>
%html{lang: 'uk'}
  %head   
    = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
   bla-bla-bla
    = js_page_specific_include   
   bla-bla-bla  

0

पहला: Application.js \\=require_treeसे हटा दें । दूसरा: आपके सभी JS कोड को बदल दिया जाना चाहिए /app/assets/javascritptऔर आपके सभी CSS कोड को बदल दिया जाना चाहिए/app/assets/stylesheets


-2

रयान से लीड के बाद, यहाँ मैंने क्या किया है-

application.js.coffee

$ ->
    view_method_name = $("body").data("view") + "_onload"
    eval("#{view_method_name}()") if eval("typeof #{view_method_name} == 'function'")
    view_action_method_name = $("body").data("view") + "_"+$("body").data("action")+"_onload"
    eval("#{view_action_method_name}()") if eval("typeof #{view_action_method_name} == 'function'")

users.js.cfish (नियंत्रक विशिष्ट कॉफ़ीस्क्रिप्ट, जैसे नियंत्रक: उपयोगकर्ता, कार्रवाई: डैशबोर्ड)

window.users_dashboard_onload = () ->
    alert("controller action called")
window.users_onload = () ->
    alert("controller called")

application.html.haml

%body{:data=>{:view=>controller.controller_name, :action=>controller.action_name}}

Downvoting। यह हास्यास्पद रूप से जटिल है - असुरक्षित ( evalयदि आपके HTML एक फटा हुआ सर्वर या किसी दुर्भावनापूर्ण उपयोगकर्ता द्वारा समझौता हो जाता है) के कारण उल्लेख नहीं है ।
मार्नेन लाईबो-कोसर

-3

यह कैसे करना है विशेष रूप से अगर आपको अपने विशिष्ट पृष्ठ के लिए टन पुस्तकालयों को निष्पादित करने की आवश्यकता नहीं है, लेकिन केवल जेएस की कुछ सैकड़ों लाइनों को कम या ज्यादा चलाने के लिए।

चूंकि यह जावास्क्रिप्ट कोड को HTML में एम्बेड करने के लिए पूरी तरह से ठीक है, बस एप्लिकेशन / विचार साझा करें। जेएस निर्देशिका के तहत बनाएं और अपने पृष्ठ / पृष्ठ विशिष्ट कोड my_cool_partial.html.erb के अंदर रखें

<script type="text/javascript"> 
<!--
  var your_code_goes_here = 0;
  function etc() {
     ...
  }
-->
</script>

तो अब आप जहाँ से भी चाहें बस कर सकते हैं:

  = render :partial => 'shared.js/my_cool_partial'

और वह यह है, के?


2
Downvoting। इनलाइन जावास्क्रिप्ट कभी भी उचित नहीं है। HTML में केवल मार्कअप होना चाहिए। जेएस और सीएसएस अलग, पुन: प्रयोज्य फ़ाइलों में होना चाहिए।
मार्नेन लाईबो-कोसर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.