2012-10-02 26 views
12

मैं एक सीएमएस में RequireJS एकीकृत कर रहा इसलिए मैं अपने पृष्ठ टेम्पलेट के तल पर यह रखा:लोड आवश्यकताएँ जेएस मॉड्यूल एचटीएमएल बॉडी इनलाइन करता है?

<html> 
<body> 
    {Placeholder1} 
    <script src="scripts/require.js" data-main="scripts/main"></script> 
    {Placeholder2} 
</body> 
</html> 

तो प्रत्येक पृष्ठ पर, मैं एक समारोह है कि RequireJS का लाभ उठाता है बनाना चाहते हैं। इसलिए मैं पृष्ठ के तल पर इस रखने की कोशिश की:

<html> 
<body> 
    <h1>Home</h1> 
    <div class="slider">Slider content</div> 

    <script src="scripts/require.js" data-main="scripts/main"></script> 

    <script type="text/javascript"> 
     require([ 
     'jquery', 
     'utils', 
     'slider' 
     ], function ($, utils, slider) { 
     slider.start(); 
     }); 
    </script> 
</body> 
</html> 

लेकिन मैं jQuery, utils और स्लाइडर js फ़ाइलों पर 404 के हो रही है। ऐसा लगता है कि यह मेरे main.js कॉन्फ़िगरेशन कि मैं पढ़ नहीं है:

require.config({ 
    paths: { 
     jquery: 'libs/jquery-1.8.1.min', 
     utils: 'libs/utils', 
     slider: 'libs/jquery.slider.min' 
    }, 
    shim: { 
     slider: ['jquery'] 
    } 
}); 

require([ 'utils' ], function (utils) { 
    utils.init(); 
}); 

मैं लोड हो रहा है RequireJS और मुख्य करने की कोशिश की पेज सिर में, लेकिन असंगत परिणाम है कि जिस तरह से मिला है। कभी-कभी jquery, utils और स्लाइडर समय और अन्य बार लोड नहीं किया जाएगा। ऐसा लगता है कि पृष्ठ के निचले हिस्से में इनलाइन "आवश्यकता" पृष्ठ पर मुख्य आवश्यकताजेएस या निर्भरता नियमों से अवगत नहीं है, लेकिन मेरा ब्रेकपॉइंट main.js में हिट करता है, इसलिए मुझे पता है कि इसे कहा जा रहा है। क्या ऐसा इसलिए है क्योंकि main.js को असीमित रूप से लोड किया जाता है लेकिन पेज के निचले हिस्से में मेरी इनलाइन "आवश्यकता" ब्लॉक पेज रेंडर पर लोड हो जाती है? मैं इसके आसपास कैसे पहुंचू?

मैंने पहले से ही आवश्यकताएँ आवश्यक है लेकिन सीएमएस के बिना। मैंने हमेशा "परिभाषित" का उपयोग किया था और मॉड्यूल को हमेशा अचूक रूप से बुलाया था, लेकिन इस तरह RequJS फ़ंक्शन इनलाइन को कभी भी कॉल नहीं करना पड़ा। ऐसा करने के सही तरीके पर कोई विचार?

उत्तर

12

यहां महत्वपूर्ण बात यह है कि config विकल्प किसी भी मॉड्यूल का अनुरोध कर रहे हैं से पहले सेट कर रहे हैं। जैसा कि आपने सही ढंग से पहचाना है, वहां रेस स्थितियां हैं जिसका मतलब है कि आपके main.js में कॉन्फ़िगरेशन विकल्प समय पर लोड नहीं होते हैं। require.js स्क्रिप्ट लोड होने से पहले कॉन्फ़िगरेशन विकल्प इनलाइन को डालने के लिए सबसे आसान तरीका होगा।

<script> 
var require = { 
    baseUrl: <?= $someVar ?>, 
    paths: { 
     // etc 
    } 
} 
</script> 
<script src="scripts/require.js" data-main="scripts/main"></script> 
पृष्ठ में और नीचे

:

<script> 
    require([ 
     'jquery', 
     'utils', 
     'slider' 
     ], function ($, utils, slider) { 
     slider.start(); 
     }); 
</script> 

भी देखें How does RequireJS work with multiple pages and partial views?

+1

इस सेटअप के साथ एक समस्या यह है कि स्क्रिप्ट/मुख्य फ़ाइल में एकाधिक मॉड्यूल होते हैं (आमतौर पर जब आरजेजे ऑप्टिमाइज़र का उपयोग किया जाता है) संसाधनों को दो बार लोड किया जा सकता है। यह एक विशेष रूप से एक समस्या है यदि यह एक फ़ाइल है जो आवश्यक परिभाषा का उपयोग नहीं कर रही है। मान लीजिए कि 'स्क्रिप्ट/मुख्य' फ़ाइल में कम जेएस मॉड्यूल शामिल है। इसके अलावा, मान लें कि इनलाइन की आवश्यकता कॉल को भी इस मॉड्यूल की आवश्यकता है।अब यदि मुख्य स्क्रिप्ट लोड होने से पहले इनलाइन कॉल का उपयोग किया जाता है (आमतौर पर मामला क्या होता है) मॉड्यूल दो बार प्राप्त किया जाएगा। यदि सामग्री एएमडी मॉड्यूल नहीं है तो इससे त्रुटियां हो सकती हैं! –

6

यह क्या हो रहा है की तरह लगता है कि main.js एसिंक्रोनस रूप से लोड होने की आवश्यकता होती है, जबकि इनलाइन तुरंत कहा जाता है। यही कारण है कि असंगत परिणाम हैं। समाधान डेटा-मुख्य विशेषता का उपयोग नहीं करना है और main.js फ़ाइल को require.js स्क्रिप्ट टैग के नीचे स्क्रिप्ट टैग के माध्यम से कॉल करना है।

आप अभी भी वहाँ में ऐसा करने से भरी हुई main.js फ़ाइल से baseurl निर्धारित कर सकते हैं:

//DETERMINE BASE URL FROM CURRENT SCRIPT PATH 
var scripts = document.getElementsByTagName("script"); 
var src = scripts[scripts.length-1].src; 
var baseUrl = src.substring(src.indexOf(document.location.pathname), src.lastIndexOf('/')); 

//CONFIGURE LIBRARIES AND DEPENDENCIES VIA REQUIREJS 
require.config({ 
    baseUrl: baseUrl, 
.... 
+0

या में main.js बजाय फाइल आप अपने इनलाइन कोड डाल सकता है। या आप अपना पथ कोड के इनलाइन ब्लॉक में परिभाषित कर सकते हैं। – dqhendricks

+0

RequJS का उपयोग करने के कारणों में से एक वैश्विक चर पर निर्भरता से बचने के लिए है, इसलिए ऐसा करने से बचें। सलाह के लिए –

+0

@ सिमन, thx। सीएमएस सिस्टम के साथ इसे टालना मुश्किल है। मेरी राय में, लगभग सभी सीएमएस पुराने हैं। – Basem