2012-03-14 10 views
5

Jaki byłby najodpowiedniejszy sposób udostępniania połączenia z bazą danych w poniższym fragmencie kodu (zmienna db) z moimi routerami/kontrolerami bez przekształcania zmiennej db w globalną?Udostępnianie obiektów i unikanie globali w pliku node.js

var mongo = require('mongoskin'), 
db = mongo.db(config.db.adress); 

app.use(function(req, res, next) { 
    db.open(function(err, data) { 
     (err) ? res.send('Internal server error', 500) : next(); 
    }); 
}); 

// Setting up controllers here 
app.post('/users', require('./controllers/users').create); 

Jadąc od tła PHP, doszedłem do myślenia o Dependency Injection, ale nie mam pojęcia, czy to jest właściwe w węźle.

+0

nie widzę problemu ??? Jest już dostępny w wewnętrznej funkcji już w twoim przykładzie. Jeśli nie określisz funkcji wbudowanej, ale wywołasz ją zaimportowaną z innego modułu, po prostu nadaj jej tę funkcję jako parametrowi, prawdopodobnie umieszczając wywołanie tego (zewnętrznego) fn wewnątrz anonimowego fn, jak już pokazano w twoim przykładzie. –

+0

Po edycji: nadaj mu funkcję wywoływaną z parametru "require" -d jako parametr (i upewnij się, że rzeczywiście używasz tego parametru tam, na przykład, aby ustawić zmienny globalny modułu, aby zapamiętał go dla innych funkcji tego modułu). Lub, daj to jako parametr dowolnej funkcji, która potrzebuje dostępu do bazy danych - co i tak byłoby czystszym programowaniem (do pewnego punktu). –

+0

Przepraszam za zamieszanie. Zaktualizowałem kod w moim pytaniu, aby zawierał przykład mojej konfiguracji tras/kontrolera. Nie ma problemu z obsługą błędów, ale wciąż jestem bardzo zdezorientowany z tego, co powinienem zrobić, aby uzyskać dostęp do obiektu 'db' z poziomu kontrolera' users', w tym przypadku, bez uprzedniego przekształcenia 'db' w globalny. – Industrial

Odpowiedz

7

Spróbuj spojrzeć na to sposób:

app.js:

var mongo = require('mongoskin'), 
db = mongo.db(config.db.adress); 

app.use(function(req, res, next) { 
    db.open(function(err, data) { 
     (err) ? res.send('Internal server error', 500) : next(); 
    }); 
}); 

require('./controllers/users')(app, db); 

controllers/users.js:

module.exports = function (app, db) { 

    app.post('/users', function(req, res, next) { 
     // Your create function 
     // Link to db exists here 
    }); 

}; 
+1

Używam również tej metody. Jest to najlepsza metoda, która dotychczas nie zastąpiła logiki 'require'. Jeśli jest dużo stanów do przekazania, zamiast przekazywać je jeden po drugim, można zamiast tego przekazać obiekt hash z wszystkimi wymaganymi depami. – chakrit

+0

Uratowałeś mój dzień! –

2

skończyło się używając odpowiedź Vadim Baryshev i trwało to trochę Ponadto, tworząc moduł State, przechowujący powszechnie używane moduły, aby zachować porządek:

state.js:

module.exports = { 
    mongo: require('mongoskin'), 
    db: require('mongoskin').db('myProject-' +process.env.NODE_ENV) 
} 

app.js:

var state = require('./state'); 
require('./controllers/Users')(app, state); 

controllers/users.js:

module.exports = function (app, state) { 

    app.post('/users', function(req, res, next) { 
     state.db.find({}, function(doc, err) {}); 
    }); 

}; 
5

nie mam żadnego doświadczenia z mongoskin ale Mongoose starannie pomija to problem polegający na zwracaniu instancji Singleton mangusty za każdym razem, kiedy tego potrzebujesz.

Umożliwia to utworzenie połączenia tylko raz (zwykle w aplikacji init) i po prostu go użyć, wysyłając zapytania do modeli, gdy są potrzebne.

Pozwala także na definiowanie modeli kiedyś tak:

var mongoose = require('mongoose'), 

    TodoSchema = new mongoose.Schema({ 
    title: { 'type': String, 'default': 'empty todo...' }, 
    order: { 'type': Number }, 
    done: { 'type': Boolean, 'default': false } 
    }); 

mongoose.model('Todo', TodoSchema); 

a następnie wykorzystać je wszędzie tam, gdzie trzeba lubić to:

var mongoose = require('mongoose'), 
     Todo = mongoose.model('Todo'); 

Więcej informacji na temat Mongoose działa tak, z przykładowym kodem można znaleźć w this answer here.

Od docs mongoskin jest, wygląda na to trzeba połączyć za każdym razem chcesz go używać, które można uprościć przez owinięcie połączenia db w pliku można wymagać:

db.js

exports.db = require('mongoskin').db('myProject-' + process.env.NODE_ENV); 

użyć:

var db = require('./db'); 

db.open(function(err, data) { 
     (err) ? res.send('Internal server error', 500) : next(); 
    }); 

Powyższa metoda, w dB jest przekazywany jako argument do każdej funkcji, może zaistnieć potrzeba, prowadzi do zwrotnego do zupy i należy go unikać, jeśli POSS ible.

0

Zgodnie z sugestią @Jed Watson moduł moongoose używa wzorca singleton (anti?), Który jest wymuszany przez mechanizm require/export.Oto konkretny fragment kodu:

(jak znaleźć tutaj: https://github.com/LearnBoost/mongoose/blob/master/lib/index.js)

/*! 
* The exports object is an instance of Mongoose. 
* 
* @api public 
*/ 

var mongoose = module.exports = exports = new Mongoose; 
Powiązane problemy