2011-02-02 7 views
62

Ho un numero di "classi" JavaScript implementate ciascuna nel proprio file JavaScript. Per lo sviluppo questi file vengono caricati singolarmente e per la produzione sono concatenati, ma in entrambi i casi devo definire manualmente un ordine di caricamento, assicurandomi che B arrivi dopo A se B usa A. Sto pensando di usare RequireJS come implementazione di CommonJS Modules/AsynchronousDefinition per risolvere questo problema automaticamente.RequireJS: come definire i moduli che contengono una singola "classe"?

C'è un modo migliore per farlo rispetto alla definizione di moduli che ogni esportazione una classe? In caso negativo, come si chiama ciò che il modulo esporta? Un modulo "impiegato" che esporta una classe "Dipendente", come nell'esempio seguente, non ritiene che sia sufficiente a me lo DRY.

define("employee", ["exports"], function(exports) { 
    exports.Employee = function(first, last) { 
     this.first = first; 
     this.last = last; 
    }; 
}); 

define("main", ["employee"], function (employee) { 
    var john = new employee.Employee("John", "Smith"); 
}); 

risposta

108

Il AMD proposal consente di restituire un valore per l'oggetto esportato. Ma si noti che è una caratteristica della proposta AMD, è solo una proposta di API e renderà più difficile tradurre il modulo in un normale modulo CommonJS. Penso che sia OK, ma informazioni utili da sapere.

in modo da poter effettuare le seguenti operazioni:

preferisco moduli che esportano una funzione di costruzione per iniziare con un nome maiuscolo, così la versione non ottimizzata di questo modulo sarebbe anche in Employee.js

define("Employee", function() { 
    //You can name this function here, 
    //which can help in debuggers but 
    //has no impact on the module name. 
    return function Employee(first, last) { 
     this.first = first; 
     this.last = last; 
    }; 
}); 

Ora in un altro modulo, è possibile utilizzare il modulo impiegato in questo modo:

define("main", ["Employee"], function (Employee) { 
    var john = new Employee("John", "Smith"); 
}); 
+0

Wow, una risposta direttamente da @jrburke, sig. RequireJS stesso! +1! – Bart

98

in aggiunta alla risposta di jrburke, notare che non c'è bisogno di restituire il c funzione di onstructor direttamente. Per le classi più utili si potrà anche aggiungere i metodi tramite il prototipo, che si può fare in questo modo:

define('Employee', function() { 
    // Start with the constructor 
    function Employee(firstName, lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    // Now add methods 
    Employee.prototype.fullName = function() { 
     return this.firstName + ' ' + this.lastName; 
    }; 

    // etc. 

    // And now return the constructor function 
    return Employee; 
}); 

In realtà questo è esattamente il modello mostrato in this example at requirejs.org.

+1

Ciao Mark, il tuo post è esattamente quello che sto cercando. Tranne una cosa È possibile definire alcuni campi per l'oggetto Employee che non fanno parte del costruttore? Ad esempio, proprietà posizione e metodo positionToUpper, ma in qualche modo definire tale proprietà non nel costruttore employee = new Employee ('john', 'smith'); employee.position = 'manager'; Avviso (employee.positionToUpper()); –

+4

Alex, questo esempio mi è stato di aiuto, è molto ben documentato e può probabilmente fornire gli esempi che stai cercando: https://gist.github.com/jonnyreeves/2474026 –

+0

@NathanPrather è un ottimo riferimento - i commenti hanno aiutato a tradurre io da uno sfondo java – y3sh