ExpressJS并在不同的路由文件之间传递变量

dzm*_*dzm 10 javascript node.js express

我正在将ExpressJs与Node.js一起使用,并将所有路由放入'routes'文件夹中.

在服务器上,我进行数据库连接,然后定义我的路由,如下所示:

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

var db;
dbconnect = new mongo.Db(config.mongo_database, new mongo.Server(config.mongo_host, config.mongo_port, {}), {});
dbconnect.open(function (err, db) {

  db.authenticate(config.mongo_user, config.mongo_pass, function (err, success) {
    if (success) {

      //routes/index.js
      app.get('/', routes.index);

      //routes/users.js
      app.get('/users', routes.users);

    }
  });
});
Run Code Online (Sandbox Code Playgroud)

我想访问每个这些路由javascript文件中的'db'对象.我如何将这个'app.js'文件传递给index.js或users.js?

谢谢!

Bra*_*ris 13

如果您在自己的文件/模块中编写数据库抽象,则可以根据需要在整个代码库中重复使用它,只需要在必要时使用require().如果正确编写它将不会重新创建,并且可以像应用程序一样在应用程序启动时初始化一次.

//contents of your database.js file
var database;

module.exports = {

    init : function(config, cb) {
        database = new mongo.Db(config.mongo_database, new mongo.Server(config.mongo_host, config.mongo_port, {}), {});
        database.open(function (err, db) {  
            db.authenticate(config.mongo_user, config.mongo_pass, cb);
        });
    },

    query : function(params, cb) {
        database.query(params, cb);
    }   

};
Run Code Online (Sandbox Code Playgroud)

这是一个微不足道的例子,但希望它得到了重点.在控制器或您需要该数据库对象的任何文件中,您只需......

var db = require('database');

db.init(params, function(err, db) {
    ...
});


db.query(params, function(err, db) {
    ...
});
Run Code Online (Sandbox Code Playgroud)

好处是,您现在拥有一个松散耦合的数据库对象,可以像应用任何其他节点模块一样通过require语句在应用程序中的任何位置使用.

  • 我喜欢这个.另一个有用的模式是将一个对象代表您的应用程序(或应用程序资源)作为对象.例如require('./ myapp.js').db或require('./ myapp.js').config (2认同)

Lin*_*iel 4

一个建议是通过接受参数的函数公开您的路线db

路线.js:

module.exports = function(db) {
    return {
        index: function(req, res, next) {
            // Funky db get stuff
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

将值包装在像这样的闭包中并返回具有更多函数的对象是一种有用的模式,有时称为“显示模块模式”。它清楚地显示了依赖关系,允许轻松测试(例如使用模拟数据库对象),同时仍然使用灵活的功能方法。

  • 缺点是现在每次你想在控制器之间重用一个“模块”时,你都必须将它添加到签名中,最终可能会遇到一些控制器需要 2 个、一些控制器需要 3 个、一个需要 5 个的情况,现在你我们的签名必须能够容纳最大公约数。我认为更好的方法是将数据库行为封装在它自己的松散耦合模块中。 (4认同)
  • @BradHarris:这绝对是一个缺点。如果您认为这很重要,保持相同签名的一种方法是接受带有参数的对象:“{db: db, foo: foo, bar: bar}”。您的解决方案绝对不是一个糟糕的解决方法,尽管它有其自身的缺点 - 例如单元测试更困难。 (2认同)