Подтвердить что ты не робот

Dojo AMD: невозможно вызвать функцию внутри требуемого

Я действительно новичок в dojo, но когда я начал разрабатывать новое приложение с dojo версией 1.7.2, я также хотел использовать новый синтаксис AMD для функций. К сожалению, я, похоже, не понимаю.:-(

Что меня больше всего раздражает, так это то, что я не могу просто вызвать любую функцию, которая находится внутри "require" -block. Например, у меня есть страница, которая при открытии создает динамическую таблицу с несколькими виджетами в каждой строке. Затем у меня есть кнопка, которая каждый раз добавляет одну пустую строку.

Без синтаксиса AMD было бы легко:
- поместите все мои "dojo.require()" в HEAD
- а затем создайте кучу моих собственных функций для создания таблицы и виджетов
- функция добавления строки может легко получить доступ к любым глобальным переменным, которые моя предыдущая заполненная функция

Но с 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? Или вы ставите все функции внутри одного "запроса" с полным списком?
Если вы сделаете это вторым способом, как вы можете вызывать эти функции из событий виджетов?

4b9b3361

Ответ 1

Самый простой способ - определить свой собственный модуль. Взгляните на этот учебник сначала:

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>

Ответ 2

Попробуйте следующее:

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();
}