2012-03-08 70 views
13

我確實是dojo的新手,但是當我開始使用dojo版本1.7.2開發新應用程序時,我也想使用新的AMD語法來實現功能。不幸的是我似乎沒有得到它。 :-(Dojo AMD:無法在需求中調用函數

什麼最苦惱的是,我不能簡單地調用任何函數,它是一個「規定」 - 塊內。 比如我有一個關於開放與幾個小部件創建一個動態表頁面。每一行 然後,我有一個按鈕,添加一個空行每次按

沒有AMD語法會很容易:
- 把我的「dojo.require()」中的HEAD
- 和然後創建一堆我自己的函數來創建表格和小部件
- 添加行函數可以很容易地訪問我以前的func中的任何全局變量重刑充滿

但隨着AMD公司這樣的:

初始函數創建表和窗口小部件:

function fillReportTable(repId) { 
require(["dojo/dom-construct", "dojo/dom-attr", "dijit/form/FilteringSelect", 
"dojo/data/ItemFileReadStore", "dijit/form/ComboBox", "dijit/form/DateTextBox", "dijit/form/Select", "dojo/store/Memory"], 
    function (domConstruct, domAttr, FilteringSelect, ItemFileReadStore, ComboBox, DateTextBox, Select, Memory) { 
    // a lot of code to create the table, consisting of SEVERAL functions 
    function createNewRow(tbl) { ...} 
    function function1() {... } 
    function function2() {... } 
    function function3() {... } 
} 

現在的「添加空行」按鍵,就其自身的功能「addEmptyRow」。
但是在這個函數中,我必須:
- 對每個dojo模塊再次做其他要求
- 我不能使用「fillReportTable」函數中的「內部」的任何函數。例如「createNewRow」功能

function addEmptyRow() { 
require(["dojo/dom-construct", "dojo/dom-attr", "dijit/form/FilteringSelect", 
"dojo/data/ItemFileReadStore", "dijit/form/ComboBox", "dijit/form/DateTextBox", "dijit/form/Select", "dojo/store/Memory"], 
    function (domConstruct, domAttr, FilteringSelect, ItemFileReadStore, ComboBox, DateTextBox, Select, Memory) { 
// a lot of code to create the table, consisting of SEVERAL functions 
} 

這一切似乎都與AMD非常複雜。
或者我錯過了明顯的東西在這裏?
對於AMD來說,如果你將代碼分成許多小功能,你是否會重複執行EACH函數中的「require」?或者你把所有的功能都放在一個「需求」裏面的完整列表中?
如果你這樣做了第二種方式,你如何從小部件事件調用這些函數?

回答

11

最簡單的方法是定義你自己的模塊。看看這個教程第一:

http://dojotoolkit.org/documentation/tutorials/1.7/modules/

現在定義自己的模塊,例如「./js/mymodules/mymodule.js」(相對於HTML頁面):

define([ 
    "dojo/dom-construct", 
    "dojo/dom-attr", 
    "dijit/form/FilteringSelect", 
    "dojo/data/ItemFileReadStore", 
    "dijit/form/ComboBox", 
    "dijit/form/DateTextBox", 
    "dijit/form/Select", 
    "dojo/store/Memory" 
], function (domConstruct, domAttr, FilteringSelect, ItemFileReadStore, ComboBox, DateTextBox, Select, Memory) { 

    function fillReportTable(repId) { 
     // a lot of code to create the table, consisting of SEVERAL functions 
     function createNewRow(tbl) { ...} 
     function function1() {... } 
     function function2() {... } 
     function function3() {... } 
    } 

    function addEmptyRow() { 
     // a lot of code to create the table, consisting of SEVERAL functions 
    } 

    // Return an object that exposes two functions 
    return { 
     fillReportTable: fillReportTable, 
     addEmptyRow: addEmptyRow 
    } 

}); 

和使用模塊是這樣的:

<html> 

<head> 

<script> 
var dojoConfig = { 
    baseUrl: "./js/", 
    packages: [ 
     { name: "dojo", location: "lib/dojo" }, 
     { name: "dijit", location: "lib/dijit" }, 
     { name: "dojox", location: "lib/dojox" } 
    ] 
}; 
</script> 

<script data-dojo-config="async: true" src="js/lib/dojo/dojo.js"></script> 

</head> 

... 

<script> 
require([ 
    "mymodules/mymodule" 
], function (mymodule) { 
    mymodule.fillReportTable(...); 
    mymodule.addEmptyRow(...); 
}); 
</script> 
+0

所以,'fillReportTable:在返回的對象fillReportTable'會暴露'fillReportTable()'函數? – joakimdahlstrom 2012-03-09 15:32:34

+0

是的,沒錯。當* mymodule *模塊爲'require'd時,AMD加載器將加載該模塊的特定JS文件(在我們的例子中爲'mymodules/mymodule.js'。在該JS文件中,您將函數傳遞給'define',並且這個函數用來'導出'模塊的功能,在你的情況下,模塊表示一個有兩個輔助函數的對象 – 2012-03-09 16:28:10

+0

所以現在我可以在require之外的任何地方調用mymodule.fillReportTable()? – Andy 2012-04-05 20:02:49

4

試試這個:

require([...], function() { 
    var myFunctions = dojo.getObject('myFunctions', true); 
    myFunctions.createNewRow = function(...) { 
     ... 
    }; 
}); 

您現在可以通過使用

myFunctions.createNewRow(); 

從任何地方打電話給你的功能。如果你不想 'myFunctions',你可以做

require([...], function() { 
    var createNewRow = function(...) {}; 

    dojo.setObject('createNewRow', createNewRow); 
}); 
3

保羅污穢物給你一個很好的例子,所以我我只是分享一些想法。

你沒有定義每個函數中的所有模塊,這是一個巨大的空間浪費。雖然,即使您嘗試多次加載模塊,Dojo也只會一次加載它。

這是我最新的項目一個簡化的模塊,用毫無意義的功能:

//app module in 'my' folder 

define(
[ 
    'app/elements', 
    'dojo/query', 
    'dojo/on', 
    'dojo/fx', 
    'dojo/_base/fx', 
    'dojo/dom-construct', 
    'dojo/_base/event' 

    //and so on..... 
], 

function(elements, q, on, fx, baseFx, constr, event) 
{ 
    return { 

     init : function() 
     { 
      var node = q(elements.loading); 
      this.removeNode(node); 

      this.addEvents(); 
     }, 

     removeNode : function(node) 
     { 
      node.remove(); 
     }, 

     addEvents : function() 
     { 
      $(elements.buttons).on('click', function(e) 
      { 
       alert(q(e).attr('id') + ' was clicked!'); 
      }); 
     } 
    } 
} 

然後我得到的模塊使用

define(
[ 
    'my/app', 
], 

function (app) 
{ 
    app.init(); 
}