2012-02-08 5 views
32

Sto passando un po 'di tempo con Dojo e la nuova struttura AMD, e spero davvero che qualcuno possa far luce sull'intero concetto. Ho vissuto su Google nelle ultime settimane cercando di trovare informazioni su non l'utilizzo, ma la struttura e le tendenze del modello di progettazione nell'utilizzo di questo.Dojo require() e AMD (1.7)

Trovo strano che per un'applicazione javascript relativamente complessa, ad esempio per una pagina principale in cui i Dijits devono essere creati e disegnati, elementi DOM creati, ecc., Ho bisogno di richiedere, e quindi utilizzare, un TON di diversi moduli che erano altrimenti disponibili nel namespace dojo prima del sistema AMD (o, almeno, non assegnati a 23 diversi vars).

Esempio:

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 
} 

Questo è solo alcuni dei moduli per una delle pagine su cui sto lavorando. Sicuramente c'è un modo migliore, non irrinunciabile in futuro per accedere a questi metodi, ecc. Voglio dire, devo davvero importare un modulo completamente nuovo per usare byId()? E ancora un altro per collegare eventi? Inoltre, tutta la confusione creata dall'assegnazione di un nome di variabile nella lista degli argomenti delle funzioni a cui aggrapparsi sembra proprio un tale passo indietro.

Ho pensato che avresti il ​​modulo require() solo quando necessario, come il modulo , ma se ne ho bisogno più di una volta, allora è probabile che la variabile a cui è assegnata sia fuori portata, e avrei bisogno di metterlo in una chiamata domReady! o ready. reaalllyly .... ??!

Questo è il motivo per cui posso solo supporre che sia la mia mancanza di comprensione per il dojo.

Ho davvero guardato e cercato e comprato libri (anche se pre-AMD), ma questa libreria mi sta davvero dando una corsa per i miei soldi. Apprezzo la luce che chiunque può versare su questo.

Modifica per esempio

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

base al largo di questo formato, che viene utilizzato con molti esempi, sia dalla gente toolkit Dojo così come siti di terze parti, che sarebbe, secondo me, assolutamente ridicolo caricare tutti i moduli richiesti come il primo function(ready, parser, style, registy... otterrebbe più a lungo e più a lungo, e creare problemi con conflitti di denominazione, ecc

di accensione e require() ing tutti i moduli avrei bisogno durante la vita dello script appena sembra sciocco a me . Detto questo, dovrei esaminare alcuni degli script "gestore pacchetti". Ma per questo esempio, se volessi utilizzare il modulo di query in determinati luoghi, dovrei o caricarlo con il resto nell'istruzione principale require(). Capisco perché fino a un certo punto, ma cosa c'è di così male con gli spazi dei nomi generici per la sintassi dei punti? dojo.whatever? dijit.findIt()? Perché caricare il modulo, fare riferimento in un nome univoco, passare attraverso la chiusura, blah blah?

Vorrei che fosse una domanda più facile da chiedere, ma spero che abbia senso.

esasperazione

Call me un newb, ma questo è davvero .. davvero .. guida mi fa impazzire. Non sono un noob quando si tratta di Javascript (apparentemente no) ma wow. Non riesco a capire questo fuori!

Ecco cosa sto raccogliendo. In adder.js:

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

In qualche pagina master o qualsiasi altra cosa:

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

... che non segue il formato pulito require(['cg/adder']) ma qualunque cosa. Non è importante adesso.

Quindi, l'uso di adder dovrebbe essere:

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

Il più vicino ho ottenuto è stato console.log(adder) tornando 3. Sì. 3. Altrimenti, è adder is not defined.

Perché questo deve essere così difficile? Sto usando la mia carta noob su questo, perché non ho davvero idea del perché questo non si sta avvicinando.

Grazie ragazzi.

+0

Dovresti fare una nuova domanda per il followup. Qui non hai abbastanza codice per mostrarci il problema (ad esempio non definisci nemmeno 'adder'). – Domenic

+0

in base all'esempio precedente, sono necessarie solo due dipendenze modulo, dijit/form/ValidationTextBox e dojo/query, in una singola istruzione require. Le dipendenze transitive si prendono cura di te. Come dice @Domenic, forse c'è di più qui e dovremmo ricominciare da capo. – peller

+0

Non lo sono? Hmm sì, ricomincio da capo. Grazie ragazzi. Saluti – Phix

risposta

20

Il formato matrice dipendenza:

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

può infatti essere fastidioso e soggetto ad errori. Abbinare le voci dell'array ai parametri delle funzioni è un vero dolore.

preferisco il formato require ("Simplified CommonJS Wrapper"):

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

Ciò mantiene le linee brevi e permette di riorganizzare/cancellare/aggiungere linee senza dover ricordare di cambiare le cose in due punti.

Quest'ultimo formato non funziona su PS3 e sui vecchi browser mobili Opera, ma si spera che non ti interessi.


Per quanto riguarda il motivo per fare questo, invece di namespacing manualmente gli oggetti, la risposta di @ Peller offre una buona panoramica del motivo per cui modularità è una buona cosa, e my answer to a similar question parla perché i sistemi di modulo come un modo per raggiungere la modularità AMD e sono un buona cosa.

L'unica cosa che aggiungerei alla risposta di @ peller è quella di espandere "prestare attenzione alle dipendenze rende effettivamente il codice molto migliore". Se il tuo modulo richiede troppi altri moduli, è un brutto segno! Abbiamo una regola allentata nella nostra base di codici JavaScript LOC 72K che un modulo dovrebbe essere lungo circa 100 righe e richiedere tra zero e quattro dipendenze. Ci è servito bene.

+0

un altro fatto divertente: con AMD, il codice da cui dipendi può effettivamente raccogliere i dati inutili quando il modulo non fa più riferimento. Questo non accade quando tutto viene indirizzato su un globale. – peller

+1

Inoltre, si noti che il caricatore di Dojo è asincrono (usa I/O asynch), quindi mentre supporta il CJS "immediato" richiede la firma di Show @Dominic qui, questa variante fallirà * se qualche altro codice non ha già caricato il modulo . Questo è il motivo per cui è necessario richiedere la firma di un array e una richiamata. Per quanto sia difficile il formato dell'array di dipendenza AMD, è progettato per semplificare l'attività di caricamento dei moduli in modo asincrono. CJS è stato progettato principalmente per i sistemi lato server che non hanno le stesse restrizioni dei browser web. – peller

+0

@peller FALSE. Dojo e altri caricatori compatibili con AMD useranno 'Function.prototype.toString' per analizzare il corpo della funzione di fabbrica, quindi assemblare un array di dipendenze. – Domenic

12

requirejs.org offre una buona panoramica di cosa AMD è e perché si desidera utilizzarlo. Sì, Dojo si sta muovendo verso moduli più piccoli a cui si farebbe riferimento individualmente. Il risultato è che si carica meno codice e i riferimenti ad esso sono espliciti. Prestare attenzione alle dipendenze rende in realtà un codice molto migliore, penso. AMD consente ottimizzazioni e una volta completata la migrazione, non è più necessario caricare tutto in globali. Niente più collisioni! Il blocco require() racchiude il codice che utilizza vari moduli. domready! si riferisce al caricamento del DOM e non ha nulla a che fare con le variabili in ambito.

Ad ogni modo, questa deviazione dal formato Q & A di SO. Potresti voler fare domande specifiche.

+0

Grazie per le informazioni. Daremo un'occhiata a requirejs e continueremo a fare hacking. * Originale originale * – Phix