पेज 3 ऐप में पेज विशिष्ट जावास्क्रिप्ट जोड़ने का सबसे अच्छा तरीका है?


159

रेल 3 में कुछ विनीत जावास्क्रिप्ट है जो बहुत अच्छा है।

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

उदाहरण के लिए, जहां मैंने पहले किया हो सकता है:

<%= 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();
}

इसलिए मुझे लगता है कि मेरा सवाल उस जावास्क्रिप्ट को कहाँ / कैसे शामिल करना है? मैं application.jsफ़ाइल नहीं भरना चाहता क्योंकि यह जावास्क्रिप्ट केवल इस एक दृश्य पर लागू है। क्या मुझे प्रत्येक पृष्ठ के लिए किसी तरह से एक कस्टम जावास्क्रिप्ट फ़ाइल शामिल करनी चाहिए, या इसे एक ऐसे उदाहरण चर में चिपकाना चाहिए जो हेडर के लिए दिखता है?



उन लोगों के लिए जो इस बात की पूरी समझ चाहते हैं कि यह कैसे काम करता है और सबसे अच्छा है कृपया railsapps.github.io/rails-javascript-include-external.html पढ़ें । यह इस विषय पर अब तक का सबसे अच्छा दस्तावेज है। यह न केवल रेल के लिए बल्कि वेब देव में काम करने वाले किसी भी व्यक्ति के लिए एक बेहतरीन रीड है। यही कारण है कि चीजों को रेल की तरह करना सबसे अच्छा है। मैं निश्चित रूप से अपने भविष्य के सवालों के लिए अपवित्र रेल का उपयोग करूंगा। वाह।
डटग्रिफ

2
@ केटग्रेरी कि एक नई है।
सिरो सेंटिल्ली 郝海东 冠状 iro i 法轮功 '

जवाबों:


153

मैं जो करना पसंद करता हूं, उसमें एक 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>

40
उपयोग क्यों नहीं <%= javascript_include_tag "my_javascipt_file" %> ?
एजेपी

5
@ एजेपी मेरा अनुमान है कि यह संपत्ति पाइपलाइन के उद्देश्य को पराजित करता है
लुललाला

2
@ लुलाला लेकिन जवाब में कोड वैसे भी नहीं है, लेकिन एक गड़बड़ फैशन में?
एजेपी

8
@AJP यह गड़बड़ है, लेकिन आपके उत्तर की तुलना में इसका एक कम http अनुरोध है।
लुललाला


103

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

प्रत्येक के लिए एक अलग मैनिफ़ेस्ट फ़ाइल के साथ अपने js को फ़ोल्डर्स में स्थानांतरित करें, इसलिए यदि आपके पास एक व्यवस्थापक js लाइब्रेरी है जो केवल बैकएंड पर उपयोग की जाती है, तो आप ऐसा कर सकते हैं:

  • संपत्ति
    • javascripts
      • व्यवस्थापक
        • ... js
      • admin.js (व्यवस्थापक समूह के लिए प्रकट)
      • application.js (ऐप वैश्विक समूह के लिए प्रकट)
      • वैश्विक
        • ... js

मौजूदा आवेदन में। 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

सुनिश्चित करें कि यह नया js मेनिफ़ेस्ट config / production.rb द्वारा संपादित किया गया है

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

फिर अपने पृष्ठ लेआउट को समायोजित करें ताकि आप पृष्ठ सिर के लिए कुछ अतिरिक्त js शामिल कर सकें:

<%= content_for :header %>   

फिर उन विचारों में जहां आप इस विशिष्ट js समूह (और साथ ही सामान्य अनुप्रयोग समूह) और / या किसी भी पृष्ठ-विशिष्ट js, css आदि को शामिल करना चाहते हैं:

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

आप निश्चित रूप से सीएसएस के साथ एक ही काम कर सकते हैं और इसे साइट के कुछ क्षेत्रों में लागू करने के लिए एक समान तरीके से समूह बना सकते हैं।


यदि आप अपने सभी मैनिफ़ेस्ट को एक ही स्थान पर रखते हैं, तो आप उस फ़ोल्डर में सब कुछ precompile करने के लिए रेल बता सकते हैं। इस तरह से आपको केवल एक बार production.rb को एडिट करना होगा और जो आपने इसमें जोड़ा है उसका ट्रैक न रखें।
अंडरस्ट्रेक्शन

पता नहीं था कि आप ऐसा कर सकते हैं - इसलिए आपके पास एक 'मैनिफ़ेस्ट' फ़ोल्डर हो सकता है जिसमें आपके मैनिफ़ेस्ट्स, साथ ही साथ व्यक्तिगत जेएस समूह शामिल थे? मैं इसे आज़मा सकता हूँ। मुझे लगता है कि वे डिफ़ॉल्ट रूप से थोड़ा और अधिक समझदार सेटअप था, क्योंकि ऐसा लगता है कि वे मानते हैं कि आप हर जगह आयातित एक बड़ी फ़ाइल में सभी js को ग्लोब करेंगे।
केनी ग्रांट

अजीब है, मैं एक Sprockets :: FileNotFound त्रुटि का उपयोग करता हूं अगर मैं उपयोग करता हूं //= require_tree ./global, लेकिन अगर मैं //= require_directory ./globalरेल 3.2.12 का उपयोग नहीं करता हूं ।
क्विक्स

2
ऐसा लगता है कि आप कई स्क्रिप्ट टैग के साथ समाप्त हो जाएंगे। मैंने सोचा कि परिसंपत्ति पाइपलाइन के साथ लक्ष्य सिर्फ एक स्क्रिप्ट टैग होना था? मैं सिर्फ javascripts लिखूंगा ताकि वे page-specific हों।
जिग्गी

1
मुझे लगता है मुझे समझ में आ गया। अतिरिक्त स्क्रिप्ट टैग से बचना पृष्ठ लोड समय के लिए बहुत महत्वपूर्ण है।
जिग्गी

12

इन उत्तरों ने मुझे एक टन की मदद की! अगर किसी को थोड़ा और चाहिए ...

  1. यदि आप उन्हें precompiled चाहते हैं, तो आपको जावास्क्रिप्ट को मैनिफ़ेस्ट में रखना होगा। हालाँकि, यदि आपको प्रत्येक जावास्क्रिप्ट फ़ाइल की आवश्यकता होती है, तो application.js.coffeeहर बार जब आप किसी भिन्न पृष्ठ पर जाते हैं, तो सभी javacsripts लोड हो जाएंगे, और पृष्ठ-विशिष्ट जावास्क्रिप्ट करने का उद्देश्य पराजित हो जाएगा।

इसलिए, आपको अपनी स्वयं की मैनिफ़ेस्ट फ़ाइल (जैसे speciifc.js) बनाने की आवश्यकता है जिसमें सभी पृष्ठ-विशिष्ट जावास्क्रिप्ट फ़ाइलों की आवश्यकता होगी। इसके अलावा, संशोधित require_treeसेapplication.js

एप्लिकेशन / आस्तियों / javascripts / application.js

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

एप्लिकेशन / आस्तियों / javascripts / specific.js

//= require_tree ./specific

फिर अपने environments/production.rbविकल्प में इस विकल्प को पूर्वनिर्धारित सूची में विन्यास विकल्प के साथ जोड़ें,

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

किया हुआ! सभी साझा किए गए javascripts जो हमेशा लोड किए जाने चाहिए उन्हें app/assets/javascripts/globalफ़ोल्डर में रखा जाएगा , और पृष्ठ-विशिष्ट javascripts में app/assets/javascripts/specific। आप केवल पृष्ठ-विशिष्ट javascripts जैसे दृश्य से कॉल कर सकते हैं

<%= javascript_include_tag "specific/whatever.js" %> //.js वैकल्पिक है।

यह पर्याप्त है, लेकिन मैं इसका javascript_include_tag params[:controller]भी उपयोग करना चाहता था । जब आप नियंत्रक बनाते हैं, तो संबंधित कॉफ़िशस्क्रिप्ट फ़ाइल का app/assets/javascriptsउल्लेख अन्य लोगों की तरह किया जाता है। वास्तव में नियंत्रक-विशिष्ट javascripts हैं, जो केवल तभी लोड किए जाते हैं जब उपयोगकर्ता विशिष्ट नियंत्रक दृश्य तक पहुंच जाता है।

इसलिए मैंने एक और प्रकटीकरण बनाया controller-specific.js

एप्लिकेशन / आस्तियों / javascripts / नियंत्रक-specific.js

//= require_directory .

इसमें नियंत्रकों के साथ जुड़े सभी स्वचालित रूप से जेनरेट किए गए कॉफ़ीस्क्रिप्ट शामिल होंगे। साथ ही, आपको इसे प्री-कंपाइल की गई सूची में जोड़ना होगा।

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


विस्तृत उत्तर के लिए बहुत बहुत धन्यवाद। मुझे यह लाइन कहां लगानी चाहिए javascript_include_tag params[:controller]। वर्तमान में मेरे application.html.erb में यह लाइन है javascript_include_tag 'application'। क्या मुझे इसे दूसरी पंक्ति से बदलना चाहिए?
उपमा

1
इसके अलावा, क्या मुझे इस लाइन <%= javascript_include_tag "specific/whatever.js" %>को एक content_for :headerब्लॉक में रखना चाहिए ?
उपमा

1
यह मेरे लिए अजीब है कि आपको गड़बड़ करने की आवश्यकता है config.assets.precompile। सब कुछ app/assets/javascripts/*.jsस्वचालित रूप से precompiled में नहीं है ?
एलेक्सचैफी 16

@AlexChaffee केवल स्वचालित रूप से उपलब्ध फाइलें हैं application.cssऔर application.js। दूसरों को या तो अन्य फ़ाइलों में शामिल किया जाना है, या उपयोग करना सूचीबद्ध है config.assets.precompileयहां पढ़ें
चो

घोषणा पत्र को स्थानांतरित कर दिया गया है। मैं 4.2.0 रेल चला रहा हूँ। और production.rb फ़ाइल में इस टिप्पणी को मिला: # config.assets.precompileऔर config.assets.versionस्थानांतरित कर दिया करने के लिए config / initializers / assets.rb
कर्ट

11

मुझे निम्नलिखित पसंद है ...

आपके application_helper.rb फ़ाइल में

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

और फिर अपने विशेष दृश्य में (ऐप / विचार / किताबें / index.html.erb इस उदाहरण में)

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

... लगता है मेरे लिए काम करता है।


9

यदि आप उस आवश्यक पृष्ठ विशिष्ट जावास्क्रिप्ट (I सहानुभूति) को प्राप्त करने के लिए परिसंपत्ति पाइपलाइन या आसपास के जटिल काम का उपयोग नहीं करना चाहते हैं , तो सबसे सरल और सबसे मजबूत तरीका है, जो ऊपर दिए गए उत्तरों के समान है लेकिन कम कोड के साथ ही है उपयोग:

<%= javascript_include_tag "my_javascipt_file" %>

नोट: इसके लिए एक और http अनुरोध की आवश्यकता होती है जिसमें उपयोग किए जाने वाले उत्तरों की तुलना में टैग शामिल होते हैं content_for :head


javascript_include_tagवास्तव में मैं जो देख रहा था, वह AJP
टॉम मैकेंजी

आपने "my_javascipt_file" कहाँ रखा है? संपत्ति में / javascripts? लेकिन अगर ऐसा है, तो //= require .आवेदन में एक साथ स्वचालित रूप से नहीं उठाया जाएगा ।
क्िक्स

@ लिंडस हां, //= require .उस स्क्रिप्ट को आपकी साइट पर किसी भी पेज पर लाएगा ताकि आपको केनी ग्रांट (उपयोग //= require_tree ./global) या bjg जैसा कुछ सुझाव देना पड़े।
एजेपी

1
यह मेरे लिए अब तक का सबसे आसान विधि से था, मैं बदल //= require_tree .करने के लिए //= require_directory .application.js में और फिर संपत्ति \ javascripts में किसी उप-निर्देशिका बनाया। ध्यान दें कि आपको नई निर्देशिका को config \ initializers \ आस्तियों में शामिल करना है। अपने लाइन को जोड़ने के लिए अपने js को आरंभ करने के लिए भेजें:Rails.application.config.assets.precompile += %w( new_dir/js_file.js )
Jonesy


3

मेरी समझ यह है कि एसेट पाइपलाइन का मतलब आपके सभी जेएस को एक (मिनिमाइज्ड) फाइल में मिलाने से पेज लोड-टाइम कम करना है। हालांकि यह सतह पर घृणास्पद लग सकता है, यह वास्तव में एक विशेषता है जो पहले से ही सी और रूबी जैसी लोकप्रिय भाषाओं में मौजूद है। "शामिल" टैग जैसी चीजें एक फ़ाइल के कई समावेश को रोकने के लिए होती हैं, और प्रोग्रामरों को अपने कोड को व्यवस्थित करने में मदद करने के लिए होती हैं। जब आप C में किसी प्रोग्राम को लिखते और संकलित करते हैं, तो वह सभी कोड आपके रनिंग प्रोग्राम के हर हिस्से में मौजूद होता है, लेकिन उस कोड को याद रखने के दौरान तरीके केवल मेमोरी में लोड होते हैं। एक अर्थ में, संकलित कार्यक्रम में यह गारंटी देने के लिए कुछ भी शामिल नहीं है कि कोड अच्छी तरह से मॉड्यूलर है। हम अपने कार्यक्रमों को इस तरह लिखकर कोड को मॉड्यूलर बनाते हैं, और ऑपरेटिंग सिस्टम केवल उन वस्तुओं और तरीकों को मेमोरी में लोड करता है जिनकी हमें किसी दिए गए इलाके के लिए आवश्यकता होती है। क्या "विधि-विशिष्ट समावेश" जैसी कोई चीज भी है? यदि आपका रेल एप्लिकेशन आराम कर रहा है, तो यह अनिवार्य रूप से आपके लिए पूछ रहा है।

यदि आप अपनी जावास्क्रिप्ट लिखते हैं ताकि यह पृष्ठ पर HTML तत्वों के व्यवहार को बढ़ाता है, तो वे कार्य डिज़ाइन के लिए 'पृष्ठ-विशिष्ट' हैं। यदि कुछ जटिल कोड है जो आपने इस तरह से लिखा है कि वह अपने संदर्भ की परवाह किए बिना निष्पादित करेगा, तो शायद उस कोड को एचटीएमएल तत्व के लिए बाध्यकारी माना जाए (आप बॉडी टैग का उपयोग कर सकते हैं, जैसा कि गार्बर-आयरिश विधि में वर्णित है )। यदि कोई फ़ंक्शन सशर्त रूप से निष्पादित करता है, तो प्रदर्शन संभवतः उन सभी अतिरिक्त स्क्रिप्ट टैग से छोटा होगा।

मैं पालोमा रत्न का उपयोग करने के बारे में सोच रहा हूं , जैसा कि रेल एप्लिकेशन प्रोजेक्ट में वर्णित है । फिर आप अपने जावास्क्रिप्ट को पेज-कॉल में पृष्ठ-विशिष्ट कार्यों को शामिल करके विशिष्ट बना सकते हैं:

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

आप रेल का उपयोग करते हैं, इसलिए मुझे पता है कि आप रत्नों से प्यार करते हैं :)


3

आपको अपनी जेएस या सीएसएस फ़ाइलों को परिसंपत्ति पाइपलाइन के बाहर लोड नहीं करना चाहिए क्योंकि आप महत्वपूर्ण विशेषताओं पर खो देते हैं जो रेल को इतना महान बनाते हैं। और आपको दूसरे रत्न की आवश्यकता नहीं है। मेरा मानना ​​है कि जितना संभव हो उतना कम रत्नों का उपयोग करना चाहिए, और एक मणि का उपयोग करना यहाँ आवश्यक नहीं है।

आप जो चाहते हैं उसे "नियंत्रक विशिष्ट जावास्क्रिप्ट" के रूप में जाना जाता है ("तल पर एक्शन स्पेसिफिक जावास्क्रिप्ट को शामिल किया गया है)। यह आपको एक विशिष्ट कंट्रोलर के लिए एक विशिष्ट जावास्क्रिप्ट फ़ाइल लोड करने की अनुमति देता है। अपने जावास्क्रिप्ट को किसी व्यू से कनेक्ट करने का प्रयास कर रहा है। .. , पीछे की ओर और MVC डिजाइन पैटर्न का पालन नहीं करता है। आप इसे अपने नियंत्रकों या अपने नियंत्रकों के अंदर की क्रियाओं के साथ जोड़ना चाहते हैं।

दुर्भाग्य से, जो भी कारण के लिए, रेल देवों ने फैसला किया कि डिफ़ॉल्ट रूप से, प्रत्येक पृष्ठ आपकी संपत्ति निर्देशिका में स्थित प्रत्येक जेएस फ़ाइल को लोड करेगा। उन्होंने डिफ़ॉल्ट रूप से "नियंत्रक विशिष्ट जावास्क्रिप्ट" को सक्षम करने के बजाय ऐसा करने का फैसला क्यों किया मुझे कभी पता नहीं चलेगा। यह application.js फ़ाइल के माध्यम से किया जाता है, जिसमें डिफ़ॉल्ट रूप से कोड की निम्नलिखित पंक्ति शामिल है:

//= require_tree .

यह एक निर्देश के रूप में जाना जाता है । यह है कि sprockets संपत्ति / javascripts निर्देशिका में हर JS फ़ाइल लोड करने के लिए क्या उपयोग करता है। डिफ़ॉल्ट रूप से, sprockets स्वचालित रूप से application.js और application.css को लोड करता है, और requ_tree निर्देशक अपनी निर्देशिका में हर JS और Coffee फ़ाइल को लोड करता है।

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

ठीक है, इसलिए "कंट्रोलर स्पेसिफिक जावास्क्रिप्ट" को सक्षम करने के लिए पहला कदम है कि आपके एप्लिकेशन से। कोड की आवश्यकता_ट्री कोड को हटा दिया जाए, या यदि आपको अभी भी ग्लोबल जेएस फाइलों की आवश्यकता है, तो इसे अपनी संपत्ति / जावास्क्रिप्ट निर्देशिका के भीतर एक फ़ोल्डर में बदलें। अर्थात:

//= require_tree ./global

चरण 2: अपने कॉन्‍फ़िगर / इनिशियलाइज़र / एसेट्स.rb फ़ाइल में जाएं, और निम्‍न जोड़ें:

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

इच्छित नाम नियंत्रक डालें।

चरण 3: अपने आवेदन में javascript_include_tag को बदलें। इस के साथ फ़ाइल (पैरामेस [: नियंत्रक] भाग नोट करें:

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

अपने सर्वर और वायोला को फिर से शुरू करें! जेएस फाइल जो आपके मचान के साथ उत्पन्न हुई थी, अब केवल उस नियंत्रक को लोड करने पर लोड होगी।

अपने नियंत्रक में एक विशेष कार्रवाई पर एक विशिष्ट जेएस फ़ाइल लोड करने की आवश्यकता है , IE / लेख / नया ? इसके बजाय यह करें:

application.html.erb :

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

कॉन्फ़िगर / इनिशियलाइज़र / एसेट्स ।rb :

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

फिर अपनी संपत्ति / javascripts फ़ोल्डर में नियंत्रक के रूप में एक ही नाम के साथ एक नया फ़ोल्डर जोड़ें और अपनी कार्रवाई के रूप में उसी नाम के साथ अपनी js फ़ाइल डालें। इसके बाद इसे उस विशिष्ट क्रिया पर लोड किया जाएगा।


1

ठीक है, शायद यह अब तक के सबसे खराब काम की तरह है, लेकिन मैं एक नियंत्रक विधि बनाता हूं जो सिर्फ .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"}

अगर किसी कारण से हम ऐसा नहीं करना चाहते हैं तो मुझे बताएं।


1

जेएस को जोड़ने का पसंदीदा तरीका पाद में है, इसलिए आप इस तरह से कर सकते हैं:

show.html.erb:

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

लेआउट / application.html.erb

<%= yield :footer_js %>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.