2012-03-08 10 views
13

Tôi thực sự là người mới đến dojo nhưng khi tôi bắt đầu phát triển một ứng dụng mới với phiên bản dojo 1.7.2 tôi cũng muốn sử dụng cú pháp AMD mới cho các chức năng. Thật không may tôi dường như không nhận được nó. :-(Dojo AMD: Không thể gọi hàm bên trong yêu cầu

Điều khiến tôi khó chịu nhất là tôi không thể gọi bất kỳ chức năng nào bên trong ổ khóa "yêu cầu" Ví dụ: tôi có trang mở khi tạo bảng động với nhiều tiện ích trong .. mỗi hàng Sau đó, tôi có một nút mà thêm một hàng trống mỗi lần ép

Without AMD cú pháp nó sẽ được dễ dàng:
- đặt tất cả của tôi "dojo.require()" trong các HEAD
- và sau đó tạo một loạt các chức năng của riêng tôi để tạo bảng và các tiện ích
- chức năng thêm hàng có thể dễ dàng truy cập bất kỳ biến toàn cầu nào tion điền

Nhưng với AMD của nó như thế này:

chức năng ban đầu tạo ra các bảng và widget:

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() {... } 
} 

Bây giờ vào nút "Add Row rỗng" gọi chức năng riêng của nó "addEmptyRow".
Nhưng trong chức năng này, tôi phải:
- thực hiện một yêu cầu khác cho mỗi mô-đun dojo
- Tôi KHÔNG thể sử dụng bất kỳ chức năng nào là "bên trong" của hàm "fillReportTable". Ví dụ: "createNewRow" -function

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 
} 

Điều này dường như quá phức tạp với AMD.
Hoặc tôi có thiếu điều gì đó hiển nhiên ở đây không?
Với AMD nếu bạn tách mã của mình thành nhiều hàm nhỏ, bạn có thực hiện "yêu cầu" bên trong hàm EACH một lần nữa không? Hay bạn đặt tất cả các chức năng bên trong một "yêu cầu" với danh sách đầy đủ?
Nếu bạn làm theo cách thứ hai, làm thế nào bạn có thể gọi các chức năng này từ các sự kiện widget?

Trả lời

11

Cách dễ nhất là xác định mô-đun của riêng bạn. Hãy xem hướng dẫn này trước:

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

Bây giờ xác định mô-đun riêng của bạn, ví dụ "./js/mymodules/mymodule.js" (liên quan đến trang 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 
    } 

}); 

Và sử dụng mô-đun của bạn như thế này:

<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

nên, 'fillReportTable: fillReportTable' trong đối tượng trở lại sẽ hiển thị hàm 'fillReportTable()'? – joakimdahlstrom

+0

Đúng vậy. Khi mô-đun * mymodule * là 'require'd, bộ nạp AMD sẽ tải một tệp JS cụ thể cho mô-đun đó (trong trường hợp của chúng tôi là 'mymodules/mymodule.js'. Trong tệp JS đó, bạn chuyển một hàm tới' define' và Chức năng này được sử dụng để 'xuất' chức năng của mô-đun. Trong trường hợp của bạn, mô-đun đại diện cho một đối tượng có hai hàm trợ giúp –

+0

Vì vậy, bây giờ tôi có thể gọi mymodule.fillReportTable() từ bất cứ nơi nào bên ngoài yêu cầu? – Andy

4

Hãy thử điều này:

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

Bây giờ bạn có thể gọi chức năng của bạn từ bất cứ nơi nào bằng cách sử dụng

myFunctions.createNewRow(); 

Nếu bạn không muốn 'myFunctions', bạn có thể làm

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

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

Paul bụi bẩn cho bạn một ví dụ điển hình, vì vậy tôi m chỉ chia sẻ một số suy nghĩ.

Bạn không xác định tất cả các mô-đun trong từng chức năng, đó là một sự lãng phí rất lớn của không gian. Mặc dù, ngay cả khi bạn cố tải mô-đun nhiều lần, Dojo sẽ chỉ tải nó một lần.

Đây là một module đơn giản từ dự án mới nhất của tôi, với chức năng khá vô nghĩa:

//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!'); 
      }); 
     } 
    } 
} 

Sau đó, tôi nhận được các mô-đun bằng cách sử dụng

define(
[ 
    'my/app', 
], 

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