Pergunta

Na verdade, sou um novato no dojo, mas quando comecei a desenvolver um novo aplicativo com o dojo versão 1.7.2, também quis usar a nova sintaxe AMD para funções.Infelizmente, parece que não entendi.:-(

O que mais me irrita é que não posso simplesmente chamar qualquer função que esteja dentro de um bloco "require".Por exemplo, tenho uma página que ao abrir cria uma tabela dinâmica com vários widgets em cada linha.Então eu tenho um botão que adiciona uma linha vazia cada vez que é pressionado.

Sem a sintaxe AMD seria fácil:
- coloque todos os meus "dojo.require()" no HEAD
- e então criar um monte de minhas próprias funções para criar a tabela e os widgets
- a função add row poderia acessar facilmente qualquer variável global que minha função anterior preenchesse

Mas com AMD é assim:

A função inicial cria a tabela e os widgets:

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

Agora o botão "Adicionar linha vazia" chama sua própria função "addEmptyRow".
Mas nesta função eu tenho que:
- faça outro require para cada módulo dojo novamente
- NÃO POSSO usar nenhuma das funções que estão "dentro" da função "fillReportTable".Por exemplo, a função "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
}

Tudo isso parece muito complicado com a AMD.
Ou estou faltando algo óbvio aqui?
Com a AMD, se você separar seu código em várias funções pequenas, você fará o "require" dentro de CADA função novamente?Ou você coloca todas as funções dentro de um "require" com a lista completa?
Se você fizer isso da segunda maneira, como poderá chamar essas funções a partir de eventos de widget?

Foi útil?

Solução

A maneira mais fácil seria definir seu próprio módulo.Dê uma olhada neste tutorial primeiro:

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

Agora defina seu próprio módulo, por exemplo."./js/mymodules/mymodule.js" (relativo à página 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
    }

});

E use seu módulo assim:

<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>

Outras dicas

Experimente isto:

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

Agora você pode chamar suas funções de qualquer lugar usando

myFunctions.createNewRow();

Se você não quiser 'myFunctions', você poderia fazer

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

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

Paul Grime deu um bom exemplo, então estou apenas compartilhando algumas idéias.

Você não define todos os módulos em cada função, é um enorme desperdício de espaço.Embora, mesmo se você tentar carregar um módulo várias vezes, o Dojo só o carregará uma vez.

Este é um módulo simplificado do meu projeto mais recente, com funcionalidades bastante sem sentido:

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

Então eu pego o módulo usando

define(
[
    'my/app',
], 

function (app) 
{
    app.init();
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top