Dojo AMD: не могу позвонить в функцию внутри требуемого
-
09-12-2019 - |
Вопрос
Я действительно новичок в додзё, но, как я начал разрабатывать новое приложение с версией Dojo 1.7.2, я также хотел использовать новый синтаксис AMD для функций. К сожалению, я, кажется, не понимаю этого. :-(
Что меня раздражает, в том, что я не могу просто назвать любую функцию, которая находится внутри «требует» -блок. Например у меня есть страница, которая на открытии создает динамическую таблицу с несколькими виджетами в каждой строке. Тогда у меня есть кнопка, которая добавляет одну пустую строку каждый раз нажатую.
без синтаксиса AMD Было бы легко:
- Поместите все мои «dojo.require ()» в голову
- а затем создать кучу своих собственных функций для создания таблицы и виджетов
- Функция Add Row может легко получить доступ к любым глобальным переменным, моя предыдущая функция заполнена
Но с 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 () {... }
}
.
Теперь кнопка «Добавить пустую строку» вызывает свою собственную функцию «addemptyry».
Но в этой функции мне нужно:
- сделать другое требование для каждого модуля Dojo - снова
- Я не могу использовать какие-либо из функций, которые «внутри» «FillReporttable». Например, «CreateNwrow» - функция
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, если вы разделяете свой код в много маленьких функций, вы делаете «требуют» внутри каждой функции снова и снова? Или вы помещаете все функции внутри одного «требуют» с полным списком?
Если вы сделаете это во втором пути, как вы можете вызвать эти функции из событий виджета?
Решение
The easiest way would be to define your own module. Take a look at this tutorial first:
http://dojotoolkit.org/documentation/tutorials/1.7/modules/
Now define your own module, e.g. "./js/mymodules/mymodule.js" (relative to HTML page):
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
}
});
And use your module like this:
<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>
Другие советы
Try this:
require([...], function() {
var myFunctions = dojo.getObject('myFunctions', true);
myFunctions.createNewRow = function(...) {
...
};
});
You can now call your functions from anywhere by using
myFunctions.createNewRow();
If you don't want 'myFunctions', you could do
require([...], function() {
var createNewRow = function(...) {};
dojo.setObject('createNewRow', createNewRow);
});
Paul Grime gave you a good example, so I'm just sharing some thoughts.
You don't define all the modules in each function, that's a huge waste of space. Although, even if you try to load a module multiple times, Dojo will only load it once anyway.
This is a simplified module from my latest project, with quite meaningless functionality:
//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!');
});
}
}
}
Then I get the module by using
define(
[
'my/app',
],
function (app)
{
app.init();
}