<\/HEAD>
<\/P>
Una pregunta en los foros<\/A> surgió recientemente y pensé que tal vez podría explicarla mejor en forma de una publicación de blog en lugar de una sola respuesta. ¿Cómo migrar de legacy Dojo a estilo moderno Dojo AMD?<\/EM> Esa es una pregunta válida, y una con la que luché<\/A> cuando se lanzó Dojo 1.7. Puedes consultar la Migración a 3.0<\/A> en la documentación para tener una idea de los cambios.<\/P><\/P>
Creo que a estas alturas, la gente está familiarizada con que dojo.declare ahora es un módulo llamado dojo\/_base\/_declare, pero es el uso de las partes AMD lo que causa cierta confusión.<\/P>
<\/P>
Creo que algunos de los obstáculos son simplemente entender AMD. Tuve algunos momentos de confusión al principio, ya que no estaba seguro cuándo usar require<\/SPAN> o cuándo usar define<\/SPAN> o cómo trabajar con módulos. Mis luchas iniciales fueron con requirejs y no tenía un mentor que realmente me ayudara, pero revisé documentación y publicaciones en grupos de Google para entenderlo, así que cuando se lanzó Dojo 1.7 con el cargador AMD, estaba mejor preparado.<\/P><\/P>Vamos a desglosarlo a su forma más simple y lo que verás en la mayoría de los ejemplos en el
sitio de ArcGIS Developers<\/A>.<\/P>require(["esri\/_map", "dojo\/_domReady!"], function(Map) {
var map = new Map("map", {
center: [-118, 34.5],
zoom: 8,
basemap: "topo"
});
});<\/PRE><\/P>Aquí está el temido método require<\/SPAN>. Si alguna vez has trabajado en C++\Java o lenguajes similares, puede que estés familiarizado con la función main()<\/SPAN>. Esta es la función que ocurre cuando una aplicación inicia, aquí es donde comienza la fiesta<\/EM>. El método require<\/SPAN> es la función principal de AMD<\/STRONG>. Así que en algún lugar dentro de los módulos del ArcGIS API for JavaScript descargados vía CDN cuando agregas la etiqueta script a tu página hay un archivo JavaScript llamado map.js<\/SPAN> en una carpeta llamada esri<\/SPAN> que se ve así.<\/P><\/P>define(['dependency1', 'dependency2'], function(dependency1, dependency2) {
var Map;
\/*cosas mágicas de unicornio*\/
return Map;
});<\/PRE><\/P>El método require<\/SPAN> buscará ese archivo y lo cargará asincrónicamente en tu aplicación. Cuando termina de cargar, se llama a la función en tu aplicación, lo que define qué es un Map (muy existencial<\/EM>) se devuelve desde la función. Observa que este módulo tiene sus propias dependencias, y en la función se cargan en el orden en que se solicitan. ESTO ES IMPORTANTE. El orden importa<\/EM>. Estas dependencias pueden ser funciones u objetos, o tal vez cadenas. A continuación hay un diagrama de mi libro<\/A> que puede ayudarte.<\/P><\/P>
<\/P>
<\/P>
En mi libro, uso un archivo llamado run.js<\/SPAN> que hace el método require<\/SPAN> definiendo mi
dojoConfig<\/A> y un main.js<\/SPAN> que realmente comienza a hacer el trabajo. Ese es simplemente mi estilo, pero no es el estilo definitivo.<\/P><\/P>Algunas personas se confunden con el uso de main.js<\/SPAN> y honestamente, yo también al principio. Un buen punto de referencia es el tutorial Advanced Modules<\/A> de Dojo. Citaré la parte importante bajo Configuración del Loader.<\/P><\/P>
- main<\/EM> (opcional, por defecto = main.js<\/>😞) usado para descubrir el módulo correcto para cargar si alguien intenta require el paquete mismo. Por ejemplo, si intentaras require "dojo", el archivo real que se cargaría es "\/_js\/_dojo\/_main.js". Dado que hemos sobrescrito esta propiedad para el paquete "my", si alguien requiere "my", realmente cargaría "\/_js\/_my\/_app.js".Si intentáramos require "util", que no es un paquete definido, el loader intentaría cargar "\/_js\/_util.js". Siempre debes definir todos tus paquetes en la configuración del loader.<\/BLOCKQUOTE><\/>}
Aquí hay un ejemplo de cómo podría verse uno de mis dojoConfigs, mi punto de entrada require.
var pathRX = new RegExp(\\/\\\\[^\\\\]+$\\/)
, locationPath = location.pathname.replace(pathRX, '');
require({
packages: [{
name: 'widgets',
location: locationPath + 'js\\widgets'
}, {
name: 'utils',
location: locationPath + 'js\\utils'
}, {
name: 'app',
location: locationPath + 'js'
}]
}, ['app']);
En el método require, el primer parámetro es el objeto dojoConfig, el segundo es la dependencia ['app'], este es mi punto de entrada. Así que según la documentación anterior, simplemente pidiendo por 'app', por defecto buscará por 'app/main.js'.
Si todo esto sigue siendo demasiado confuso, aún puedes definir un objeto global dojoConfig para configurar tus paquetes y hacer un require más antiguo simple para iniciar tu aplicación. Algo como esto.
<body class=\"nihilo\">
<script>
var pathRX = new RegExp(\\/\\\\[^\\\\]+$\\/)
, locationPath = location.pathname.replace(pathRX, '');
var dojoConfig = {
async: true,
isDebug: true,
packages: [
{ name: 'xstyle', location: locationPath + '\/bower_components/xstyle' },
{ name: 'mayhem', location: locationPath + '\/bower_components/mayhem/dist' },
{ name: 'app', location: locationPath + 'js' }
],
tlmSiblingOfDojo: false
};
</script>
<script>require(['app/start'], function() {})</script>
</body>
Espero que eso aclare algunas cosas un poco.
Puedes aprender mucho sobre esto a través de la documentación de Dojo y especialmente el tutorial CDN Modules. Esta página cubre algunos aspectos Legacy to Modern Dojo en profundidad. Aquí tienes una guía de migración. También puedes probar este convertidor legacy Dojo a AMD. Nunca lo he usado, pero podría ser un buen punto de partida. Dudo que funcione al 100% con todos los módulos Esri, pero vale la pena intentarlo.
Espero que eso ayude un poco si todavía estás luchando con migrar aplicaciones Legacy Dojo a moderno Dojo. Puede tomar algo de tiempo asimilarlo todo, pero lo hará. Para más consejos y trucos geodev, visita mi blog.