2013-11-04 19 views
0

我想傳遞一些參數requirejs與這樣開始:如何獲取定義requirejs主入口的<script>元素?

<script src=".../require.min.js" 
     data-main="..../config.js" 
     data-modules="sticker datepicker"> 
</script> 

這意味着我要加載的stickerdatepicker模塊像這樣config.js/main.js

var modules = modules_parameters.split(' '); 
_.each(modules, function (m) { 
    var mod = require('...' + m); 
    mod.init(); // Sticker.init(), DatePicker.init() 
}); 

的問題是如何能我得到了modules_parameters

我現在可以使用像$('script[data-main]')這樣的jquery。但由於顯然requirejs正在掃描data-main,它是否暴露一個API訪問相同的<script>標籤?

背景

我有一個的layout.html:<script src='require.js' data-main='config.js' data-modules='{placeholder}'>

和page1.html延長它:{placeholder}sticker datepicker{/placeholder}

和page2.html延長它:{placeholder}another another2{/placeholder}

,以便每個頁面加載其自己的模塊。

+0

據我所知,沒有這樣的API。但是這是可行的另一種方式,即需要配置中的'config'屬性。你會對這樣的解決方案感興趣嗎? –

+0

是的,如果jQuery自由和優雅 – hbrls

+0

@hbrlovehaku爲什麼你將模塊初始化與模塊初始化分開? DatePicker的初始化如此繁重或特殊,它需要從模塊的實例化中分離出來?除此之外,我贊同Nikos。 – Louis

回答

1

在你RequireJS配置,你可以添加一個config性質和目標運行初始化代碼模塊:

require.config({ 
    ... 
    config: { 
     "app/config": { 
      initModules: ["sticker", "datepicker"] 
     } 
    } 
    ... 
}); 
app/config模塊

現在:

define(["underscore", "module"], function(_, module) { 
    var modules = module.config().initModules; 
    _.each(modules, function (m) { 
     // do your normal code here 
    }); 
}); 

該解決方案可以應付動態定義的initModules,如果你不介意重新安排你的代碼。我通常做的是將RequireJS配置與主模塊分開。然後,我不得不從一個內嵌腳本自定義配置的機會(通常是語言首選項):

<script src="scripts/require-cfg.js"></script> 
<script> 
    require.config = require.config || {}; 
    // the array below is dynamically generated (i.e. JSP, PHP, etc) 
    require.config["app/config"].initModules = ["sticker", "datepicker"]; 
</script> 
<script src="scripts/lib/require.js"></script> 
<script> 
    // bootstrap the application 
    require("app/main"); 
</script> 

不,對於這種情況,require-cfg.js會是什麼樣子:

var require = { 
    paths: ..., 
    shim: ..., 
    config: ... 
}; 

,而不是像require.config({...});

+0

我仍在評估你的建議。它看起來不錯,但我還沒有抓到。一旦明白,我會接受答案。 – hbrls

0

我在評論中建議使模塊初始化成爲模塊實例化的一部分。 hbrlovehaku(原始提問者)詢問更多細節。評論太約束,所以我在這裏回答。

原問題的設計建議,如「日期選擇器」模塊的定義是這樣的:

define(function() { 
    function init() { 
     // Initialize here. 
    } 
    return { 
     init: init, 
    } 
}); 

所以後來有人使用一個模塊像上面必須做到:

define(["datepicker"], function (datepicker) { 
    datepicker.init(); 
}); 

這是因爲模塊實例化和模塊初始化解耦。但是,它們不一定是。模塊可以這樣定義:

define(function() { 
    // Initialize here 
}); 

通過上述設計,只要有其他模塊需要,模塊就會被初始化。請注意,傳遞到define的函數未執行,直到模塊需要「datepicker」。因此,使用「日期選擇器」模塊可以是這樣的:

define(["datepicker"], function (datepicker) { 
    // There is no need to call init. 
}); 

一個頁面則可能含有類似:

<script src="[...]/require.min.js" data-main="[...]/config.js"></script> 
<script> 
    (function() { 
     var mods = "{placeholder}".split(" "); 
     // I don' know whether the anonymous function is necessary in the next line. 
     require(mods, function() {}); 
    )(); 
</script> 

其實這個小片段上方可以適合用於即使初始化函數必要。就像這樣:

<script src="[...]/require.min.js" data-main="[...]/config.js"></script> 
<script> 
    (function() { 
     var mods = "{placeholder}".split(" "); 
     require(mods, function() { 
      Array.prototype.forEach.call(arguments, function (mod) { 
       mod.init(); 
      }); 
     }); 
    )(); 
</script> 

{placeholder}只需要與實際模塊的名稱進行替換,就像它會在data-modules="{placeholder}"

+0

我會同意你'init'並不總是必要的。但由於我不確定什麼時候是「singleton」,什麼時候不是,我選擇「初始化」它們。這絕對需要重新思考。 'Array.prototype'看起來不錯。謝謝你。 – hbrls

+0

但我目前關心的這個問題是關於如何在html模板中「定義」它們。 – hbrls

+0

@hbrlovehaku RequireJS模塊是單身人士。無論頁面的代碼爲任何給定的模塊調用「require」多少次:它的工廠函數最多隻能執行一次。 – Louis

相關問題