知道Express.js在决定应用程序结构方面几乎留给了开发人员,并且在阅读了很多有关SO的建议之后(例如,请参阅link1和link2)以及检查{ {3}},我仍然不确定我所做的是最好的前进方式。
假设我在我的应用程序中广泛使用Redis,并且我有多个需要redis客户端运行查询的“模型”,最好在主app.js中初始化redis客户端,如下所示:
var db = redis.createClient();
var models = require('./models')(db);
var routes = require('./controllers')(models);
或者在每个模型中初始化redis会更好,然后让每个控制器都需要感兴趣的模型吗?
后一种方法是我正在使用的,看起来不那么干。但是以最佳方式传递模型实例?请注意,我在这里加载多个模型/控制器 - 我不知道如何修改我的设置以将redis客户端正确地传递给每个模型。
//currently in models/index.js
exports.home = require('./home.js');
exports.users = require('./user.js');
TL; DR,我的问题是:
require('./models')(db)
更新
我尝试了index.js
的不同方法,使用module.exports
来返回模型/控制器的对象:
module.exports = function(models){
var routes = {};
routes.online = require('./home.js')(models);
routes.users = require('./user.js')(models);
return routes;
};
现在看起来好像是个好主意?
答案 0 :(得分:3)
如果我分享我最近使用SQL ORM Patio实现项目的方式,这可能很有用。更多背景:我使用的MVC框架是Locomotive,但这绝对不是一个要求(机车没有ORM,它实现了如何处理开发人员的模型和数据库,类似于Express )。
Locomotive有一个名为'initializers'的构造,它只是在app启动时加载的JS文件;他们所做的事取决于开发人员。在我的项目中,一个初始化程序配置了数据库。
初始化程序建立了实际的数据库连接,还负责加载model
目录中的所有JS文件。在伪代码中:
registry = require('model_registry'); // see below
db = createDatabaseConnection();
files = fs.readDirSync(MODEL_DIRECTORY);
for each file in files:
if filename doesn't end with '.js':
continue
mod = require(path.join(MODEL_DIRECTORY, filename));
var model = mod(db);
registry.registerModel(model);
模型看起来像这样:
// models/mymodel.js
module.exports = function(db ) {
var model = function(...) { /* model class */ };
model.modelName = 'MyModel'; // used by registry, see below
return model;
};
模型注册表是一个非常简单的模块,用于存放所有模型:
module.exports = {
registerModel : function(model) {
if (! model.hasOwnProperty('modelName'))
throw Error('[model registry] models require a modelName property');
this[model.modelName] = model;
}
};
因为模型注册表将模型类存储在this
(module.exports
)中,所以可以从需要访问模型的其他文件中导入它们:
// mycontroller.js
var MyModel = require('model_registry').MyModel;
var instance = new MyModel(...);
免责声明:这对我有用,YMMV。此外,上面的代码示例没有考虑任何异步要求或错误处理,所以在我的情况下实际的实现更精细。