問題描述
我正在將專案從”old” browser-style 模組結構更改為具有 require.js 的”new” browser-or-server-side-javascript 模組結構。
在客戶端上,我使用的是異地託管的 jQuery,所以我從他們在 README 的“use priority config” 技術中給出的例子開始:
<title>My Page</title>
<script src="scripts/require.js"></script>
<script>
require({
baseUrl: 'scripts',
paths: {
jquery: 'http://googleajax.admincdn.com/ajax/libs/jquery/1.7.2/jquery.min',
jqueryui: ...,
...
... // bunch more paths here
},
priority: ['jquery']
}, [ 'main' ]);
</script>
這實際上是正常的。但我想將功能從主要匯出到 HTML 網頁本身。例如:
<a class="button" href="#" onclick="MyApi.foo();">
<img src="foo.png" alt="foo" />Click for: <b>Foo!</b>
</a>
在嵌入 AMD 模組模式之前,我會透過在全域性空間中建立一個字典物件來從各種檔案中公開功能:
// main.js
var MyApi = {};
jQuery(document).ready(function($) {
// ...unexported code goes here...
// export function via MyApi
MyApi.foo = function() {
alert("Foo!");
};
});
但是我不知道 require.js 中的正確方法是什麼。在<script> 標籤中放入更多的 require 語句是否可以,然後命名模組,以便可以在網頁內使用?或者這應該總是在 main.js 內動態完成,比如 $('#foobutton').click(...)?
最佳解決思路
使用 AMD 的一個好處就是放棄名稱空間的需要。試圖用 RequireJS 再次建立它們將違背 AMD 推出的模式。
關於使用 main.js,只有當您有一個單一的頁面應用程式和所有的程式碼從一個地方引用時,這只是真的適當。您可以根據需要額外呼叫電話以要求和載入其他模組。
使用上面的例子,你可以這樣做:
foo.js
define(['jquery'], function($) {
// Some set up
// code here
// Return module with methods
return {
bar: function() {
}
}
});
page.js
require(['foo'], function(foo) {
// jQuery loaded by foo module so free to use it
$('.button').on('click', function(e) {
foo.bar();
e.preventDefault();
});
});
然後在您的頁面中請求帶有 require 的 page.js 檔案。
使用上面的例子:
require({
// config stuff here
}, [ 'page' ]);
或者進一步將其載入到頁面中:
<script>
require(['page']);
</script>
一些額外的點
-
使用上述模式,page.js 可以輕鬆地需要許多其他模組來載入其他頁面相關的功能。
-
在將會員附加到全域性名稱空間之前,您現在可以將該程式碼拆分成任何頁面上可以是 re-used 的單獨的模組。所有這些都不依賴於一個全域性物件。
-
使用這種方法將事件附加到你的 DOM 元素最有可能是由 RequireJS 提供的 rely on the DOM Ready module
次佳解決思路
您還可以在 javascript 的視窗類中設定引用。
在應用模組 window.MyApi = MyApi; 的底部
<a class="button" href="#" onclick="MyApi.foo();"></a>
第三種解決思路
將 onclick=""放在您的標記中,感覺很髒 – 與內容混合演示。我建議您新增一個<script> 塊,並將 require 放在其中,一旦在回撥內部,並在另一個內部 $(document).ready()內,如果需要,請以正常方式連線事件處理程序:$('#node').click(...)。如果你可以這樣做一般,它適用於多個頁面,然後把它放在一個被縮小,組合和快取的外部檔案中。但是通常這些東西最終是 page-specific,所以頁面底部的<script> 標籤是避免另外一個外部資源請求的一個很好的解決方案。
第四種思路
另一個解決方案就是使用這樣的程式碼 (當然 requirejs 必須新增到頁面中):
<input type="button" onclick="(function() { require('mymodule').do_work() })()"/>
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。