2012-10-31 9 views
77

Czy można przekazywać argumenty podczas ładowania modułu przy użyciu polecenia require?Podawanie argumentów wymagających (podczas ładowania modułu)

Mam moduł, login.js, który zapewnia funkcję logowania. Wymaga połączenia z bazą danych i chcę, aby to samo połączenie z bazą danych było używane we wszystkich moich modułach. Teraz wyeksportuję funkcję login.setDatabase (...), która pozwala mi określić połączenie z bazą danych, i to działa dobrze. Ale wolałbym przekazać bazę danych i inne wymagania podczas ładowania modułu.

var db = ... 
var login = require("./login.js")(db); 

Jestem całkiem nowy z NodeJS i zazwyczaj rozwijać przy użyciu języka Java oraz Spring Framework, więc tak ... to jest wtrysk konstruktor :) Czy można zrobić coś takiego kodu I podany powyżej?

+0

Polecam również przejrzenie odpowiedzi na [to] (http://stackoverflow.com/questions/13080771/node-js-passing-variables) pytanie. Jak wskazano w mojej odpowiedzi, powszechnym idiomem jest przekazanie obiektu 'app' do wymaganych modułów. –

+0

Zamiast robić cały ten argument przechodząc dla db, możesz użyć implementacji [singleton] (http://www.dofactory.com/javascript/singleton-design-pattern) i wywołać db.getInstance() w razie potrzeby. – wulfgarpro

Odpowiedz

168

oparciu o komentarze w this answer, robię to, co starasz się zrobić tak:

module.exports = function (app, db) { 
    var module = {}; 

    module.auth = function (req, res) { 
     // This will be available 'outside'. 
     // Authy stuff that can be used outside... 
    }; 

    // Other stuff... 
    module.pickle = function(cucumber, herbs, vinegar) { 
     // This will be available 'outside'. 
     // Pickling stuff... 
    }; 

    function jarThemPickles(pickle, jar) { 
     // This will be NOT available 'outside'. 
     // Pickling stuff... 

     return pickleJar; 
    }; 

    return module; 
}; 

I strukturę prawie wszystkie moje moduły tak. Wydaje mi się, że dobrze mi idzie.

+0

Nice. Naprawdę nie wiem, którą odpowiedź powinienem przyjąć :) Jest to dla mnie tak samo ważne jak inna odpowiedź powyżej ... dziękuję. –

+66

Nie ma to dla mnie znaczenia - po prostu cieszę się, że wreszcie porozmawiam o piklach na StackOverflow. : P – floatingLomas

+2

To powinno być oznaczone jako poprawna odpowiedź. –

27

Tak. W swoim module login wyeksportuj pojedynczą funkcję, która przyjmuje jako argument db. Na przykład:

module.exports = function(db) { 
    ... 
}; 
+1

Wypróbowałem to. W login.js 'module.exports = funkcja (około db) { ... } module.exports.auth = funkcja (REQ Res) { ... uwierzytelniania materiał }' Zadzwoń do funkcji "anonimowy" i ustawia zmienne 'app' i' db', ale gdy to zrobię, moja aplikacja nie znajdzie funkcji 'auth'. Co ja robię źle? Jeśli usuniemy anonimową funkcję, funkcja 'auth' stanie się znowu dostępna. –

+0

Podobnie jak wszystko w javascript, 'export' jest obiektem. Możesz przypisać do niego właściwości (wiele eksportów) lub możesz przypisać je do wartości. Wygląda na to, że przypisałeś eksport do funkcji, ale potem przypisano auth jako właściwość funkcji przypisanej do eksportu. Musisz więc wykonać polecenie 'var auth = require (" ./ login.js "). Auth', które może nie być zgodne z twoimi zamierzeniami. Jeśli chcesz użyć wzorca z pierwotnego pytania, prawdopodobnie najlepiej będzie trzymać się jednej wartości eksportu. Jeśli to nadal nie ma sensu, polecam opublikowanie najważniejszego dla mnie punktu widzenia. –

+1

Po ponownym przeczytaniu tego, wydaje się, że możesz przypisać 'auth' jako właściwość obiektu' exports', a następnie w module przypisałeś 'export' do funkcji (tym samym przesłaniając poprzednie przypisanie). Jeśli odwrócisz kolejność przypisań, powinieneś mieć dostęp do funkcji 'auth', zgodnie z oczekiwaniami. Ponownie trudno powiedzieć, nie widząc kodu. –

-1

Innym sposobem, aby przejść o rzeczach jest zdefiniowanie metod, a następnie udostępnienie ich poniżej poprzez „eksportu”. (Module.exports i wywóz odnosi się do tego samego obiektu)

function kamehameha(name,fame){ 


} 

function bigbangkamehameha(name){ 

} 



exports.kamehameha=kamehameha; 
exports.bigbang=bigbangkamehameha; //bigbang refers to bigbangkamehameha 
9

nie jestem pewien jeśli będzie to nadal przydatne dla ludzi, ale z ES6 mam sposób, aby to zrobić, że uważam za czysty i użyteczny.

class MyClass { 
    constructor (arg1, arg2, arg3) 
    myFunction1() {...} 
    myFunction2() {...} 
    myFunction3() {...} 
} 

module.exports = (arg1, arg2, arg3) => { return new MyClass(arg1,arg2,arg3) } 

A następnie otrzymasz oczekiwane zachowanie.

var MyClass = require('/MyClass.js')(arg1, arg2, arg3) 
Powiązane problemy