【问题标题】:ExpressJS and passing variables between separate route filesExpressJS 和在单独的路由文件之间传递变量
【发布时间】:2012-04-02 16:28:03
【问题描述】:

我将 ExpressJs 与 Node.js 一起使用,并将我的所有路由放入一个“路由”文件夹中。

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

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

    }
  });
});

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

谢谢!

【问题讨论】:

    标签: javascript node.js express


    【解决方案1】:

    如果您将数据库抽象写在它自己的文件/模块中,那么您可以根据需要在整个代码库中重用它,只需在需要的地方进行 require()'ing 即可。如果您编写正确,它将不会重新创建,并且可以像您的示例一样在应用程序启动时初始化一次。

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

    这是一个微不足道的例子,但希望它能说明问题。在需要该数据库对象的控制器或任何文件中,您只需...

    var db = require('database');
    
    db.init(params, function(err, db) {
        ...
    });
    
    
    db.query(params, function(err, db) {
        ...
    });
    

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

    【讨论】:

    • 我喜欢这个。另一个有用的模式是拥有一个将您的应用程序(或应用程序资源)表示为对象的对象。例如。 require('./myapp.js').db 或 require('./myapp.js').config
    【解决方案2】:

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

    routes.js:

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

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

    【讨论】:

    • 缺点是现在每次你想跨控制器重用一个“模块”时,你必须将它添加到签名中,你最终可能会遇到一些控制器需要2个,一些需要3个的情况,一个需要 5,现在你有一个签名,它必须容纳最大的公分母。我认为更好的方法是将您的数据库行为封装在它自己的松散耦合模块中。
    • @BradHarris:这绝对是一个缺点。如果您觉得这很重要,那么保持相同签名的一种方法是接受带有参数的对象:{db: db, foo: foo, bar: bar}。你的解决方案绝对不是一个糟糕的解决方法,尽管它也有它自己的缺点——对于一个人来说,它更难进行单元测试。
    猜你喜欢
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 2018-10-09
    • 1970-01-01
    • 2015-11-16
    • 2019-06-13
    相关资源
    最近更新 更多