2012-10-02 77 views
12

我整合RequireJS在CMS所以我把這個在我的頁面模板的底部:加載requireJS模塊內聯HTML正文?

<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 CONFIGS,我有:

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和滑塊會被加載,其他時間不會。就好像頁面底部的內聯「require」不知道頁面上的主要RequireJS或依賴關係規則,但是我的斷點在main.js中,因此我知道它正在被調用。是否因爲main.js異步加載,但頁面底部的內聯「require」塊是否在頁面呈現中加載?我如何解決這個問題?

我之前成功使用過RequireJS,但沒有使用CMS。我總是使用「define」,並且模塊總是以異步方式調用,但從不必像這樣內聯地調用RequireJS函數。任何想法正確的方式來做到這一點?

回答

12

這裏最重要的是,被請求的任何模塊之前的配置選項設置。正如您已正確識別的那樣,存在競態條件,這意味着您的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

這個設置的一個問題是當腳本/主文件包含多個模塊時(通常是使用r.js優化器的情況),資源可能會被加載兩次。如果這是一個不使用require的定義的文件,這是一個特別的問題。 我們假設'scripts/main'文件包含LESS JS模塊。此外,假設內聯需要調用也需要這個模塊。現在,如果在加載主腳本之前訪問內聯調用(通常是這種情況),模塊將獲得兩次。 如果內容不是AMD模塊,可能會導致錯誤! –

6

看來發生的情況是,main.js被異步加載,而內聯require被立即調用。這就是爲什麼有不一致的結果。解決方案是不使用data-main屬性,並通過require.js腳本標記下的腳本標記調用main.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

使用RequireJS的原因之一是爲了避免依賴全局變量,所以請避免這樣做。 –

+0

@Simon,thx的建議。使用CMS系統很難避免這種情況。在我看來,幾乎所有的CMS都過時了。 – Basem