2012-02-08 20 views
32

Tengo una transición de heckuva a Dojo y la nueva estructura de AMD, y realmente espero que alguien pueda arrojar algo de luz sobre el concepto completo. He estado viviendo en Google durante las últimas semanas tratando de encontrar información sobre el uso, pero la estructura y las tendencias del patrón de diseño en el uso de este.Dojo require() y AMD (1.7)

Me resulta extraño que para una aplicación javascript relativamente compleja, como para una página principal donde se deben crear y diseñar Dijits, crear elementos DOM, etc., que necesito requerir, y por lo tanto usar, una TONELADA de diferentes módulos que de otro modo estaban disponibles en el espacio de nombres dojo antes del sistema AMD (o, al menos, no asignados a 23 vars diferentes).

Ejemplo:

require(['dijit/form/ValidationTextBox', 'dijit/form/SimpleTextarea', 'dijit/form/CheckBox', 'dijit/Dialog', 'dijit/form/Form']) 
require(['dojo/ready', 'dojo/parser', 'dojo/dom-style', 'dijit/registry', 'dojo/dom', 'dojo/_base/connect', 'dojo/dom-construct'], 
function(ready, parser, style, registry, dom, event, construct){ 
    //...etc 
} 

Eso es sólo unos pocos de los módulos correspondientes a una de las páginas que estoy trabajando. Seguramente hay una mejor manera de acceder a estos métodos, sin interrupciones en el futuro. ¿Quiero decir, realmente tengo que importar un módulo completamente nuevo para usar byId()? ¿Y otra más para conectar eventos? Además de eso, todo el desorden que se crea al tener que asignar un nombre de variable en la lista de argumentos de funciones para aferrarse simplemente parece un retroceso.

Pensé que tal vez require() el módulo solo cuando fuera necesario, como el módulo query, pero si lo necesito más de una vez, es probable que la variable a la que está asignado esté fuera de alcance, y necesitaría ponerlo en una llamada domReady! o ready. reaalllly .... ??!

Por eso solo puedo suponer que es mi falta de comprensión para el dojo.

Realmente busqué y busqué y compré libros (aunque uno anterior a AMD), pero esta biblioteca realmente me está echando a correr por mi dinero. Aprecio que alguien pueda arrojar luz sobre esto.

Editar para el Ejemplo

require(['dijit/form/ValidationTextBox']) 
require(['dojo/ready', 'dojo/parser', 'dojo/dom-style', 'dijit/registry', 'dojo/dom', 'dojo/_base/connect', 'dojo/dom-construct'], function(ready, parser, style, registry, dom, event, construct){ 
    /* perform some tasks */ 
    var _name = new dijit.form.ValidationTextBox({ 
     propercase : true, 
     tooltipPosition : ['above', 'after'] 
    }, 'name') 

    /* 
    Let's say I want to use the query module in some places, i.e. here. 
    */ 
    require(['dojo/query', 'dojo/dom-attr'], function(query, attr){ 
     query('#list li').forEach(function(li){ 
      // do something with these 
     }) 
    }) 
} 

Basado fuera de este formato, que se utiliza con muchos ejemplos tanto de la gente Dojo Toolkit, así como sitios de terceros, que sería, en mi humilde opinión, absolutamente ridículo cargue todos los módulos requeridos ya que el primer function(ready, parser, style, registy... sería más y más largo, y crearía problemas al nombrar colisiones, etc.

Encender y require() en todos los módulos que necesitaría durante la vida del guión me parece una tontería . Dicho esto, tendría que ver algunos de los scripts de "administrador de paquetes". Pero para este ejemplo, si quisiera usar el módulo de consulta en lugares seleccionados, tendría que cargarlo con el resto en la declaración principal require(). Entiendo por qué hasta cierto punto, pero ¿qué hay de malo con los espacios de nombres genéricos de sintaxis de puntos? dojo.whatever? dijit.findIt()? ¿Por qué cargar el módulo, referencia en un nombre único, pasar por el cierre, bla, bla?

Deseo que esta sea una pregunta más fácil de hacer, pero espero que tenga sentido.

La exasperación

Me llaman un Novato, pero esto es realmente .. .. realmente me está volviendo loco. No soy novato cuando se trata de Javascript (aparentemente no) pero guau. No puedo entender esto fuera!

Esto es lo que estoy reuniendo. En adder.js:

define('adder', function(require, exports){ 
    exports.addTen = function(x){ 
     return x + 10 
    } 
}) 

en alguna página maestra o lo que sea:

require(['./js/cg/adder.js']) 

... que no sigue el formato de require(['cg/adder']) ordenada, pero lo que sea. No es importante en este momento.

Entonces, el uso de adder debe ser:

console.log(adder.addTen(100)) // 110 

Lo más cerca que llegué fue console.log(adder) regresando 3. Sí. 3. De lo contrario, es adder is not defined.

¿Por qué tiene que ser tan difícil? Estoy usando mi tarjeta noob en esto, porque realmente no tengo idea de por qué esto no se está uniendo.

Gracias chicos.

+0

Debe hacer una nueva pregunta para su seguimiento. No tiene suficiente código aquí para mostrarnos el problema (por ejemplo, ni siquiera define 'sumador'). – Domenic

+0

según su ejemplo anterior, solo necesita dos dependencias de módulo, dijit/form/ValidationTextBox y dojo/query, en una única declaración require. Las dependencias transitivas se encargan de usted. Como dice @Domenic, tal vez haya más aquí y deberíamos empezar de nuevo. – peller

+0

¿No? Hmm, sí, voy a comenzar de nuevo. Gracias chicos. Cheers – Phix

Respuesta

20

La dependencia formato de matriz:

define(["a", "b", "c"], function (a, b, c) { 
}); 

de hecho puede ser molesto y propenso a errores. Hacer coincidir las entradas de la matriz con los parámetros de la función es un verdadero dolor.

prefiero el formato require ("Simplified CommonJS Wrapper"):

define(function (require) { 
    var a = require("a"); 
    var b = require("b"); 
    var c = require("c"); 
}); 

Esto mantiene sus líneas corta y permite reorganizar/eliminar/añadir líneas sin tener que recordar para cambiar las cosas en dos lugares.

Este último formato no funcionará en los navegadores de PS3 y anteriores de Opera, pero espero que no le importe.


cuanto a por qué hacer esto en lugar de namespacing manualmente objetos, la respuesta de @ peller da una buena visión general de por qué la modularidad es una buena cosa, y my answer to a similar question habla de por qué AMD y sistemas de módulos como una forma de lograr la modularidad son una Buena cosa.

Lo único que añadiría a la respuesta de @ peller es expandir "prestar atención a las dependencias realmente hace que el código sea mucho mejor". Si su módulo requiere demasiados módulos, ¡eso es una mala señal! Tenemos una regla flexible en nuestra base de códigos JavaScript de 72K LOC que un módulo debe tener ~ 100 líneas de largo y requiere entre cero y cuatro dependencias. Nos ha servido bien.

+0

Otro hecho divertido: con AMD, el código del que depende puede realmente obtener basura recolectada cuando ya no se hace referencia a su módulo. Esto no ocurre cuando todo está conectado a un global. – peller

+1

Además, tenga en cuenta que el cargador de Dojo es asíncrono (usa asincronización de E/S), por lo tanto, si bien el CJS "inmediato" requiere firma @Dominic muestra aquí, esta variante * fallará * si algún otro código aún no ha cargado el módulo . Es por eso que hay una firma requerida que toma una matriz y una devolución de llamada. Tan incómodo como es el formato de matriz de dependencia de AMD, está diseñado para simplificar la tarea de cargar módulos de forma asincrónica. CJS se diseñó principalmente para sistemas del lado del servidor que no tenían las mismas restricciones que los navegadores web. – peller

+0

@peller FALSE. Dojo y otros cargadores compatibles con AMD utilizarán 'Function.prototype.toString' para analizar el cuerpo de la función de fábrica, luego ensamblarán una matriz de dependencias. – Domenic

12

requirejs.org ofrece una visión bastante buena de lo que es AMD y por qué querría usarlo. Sí, Dojo se está moviendo hacia módulos más pequeños a los que harías referencia individualmente. El resultado es que carga menos código y sus referencias son explícitas. Prestar atención a las dependencias realmente hace que el código sea mucho mejor, creo. AMD permite optimizaciones, y una vez que se completa la migración, ya no tiene que cargar todo en globales. ¡No más colisiones! El bloque require() ajusta el código que usa varios módulos. domReady! se relaciona con la carga del DOM y no tiene nada que ver con el alcance de las variables.

De todos modos, esto se está desviando de la Q & Un formato de SO. Es posible que desee hacer preguntas específicas.

+0

Gracias por la información. Echaré un vistazo más a requirejs y seguiré pirateando esto. * Original editado * – Phix

Cuestiones relacionadas