在项目的当前状态下,你想要做的事情并不容易,而且有点混乱。我指的是 v0.10 版本。你要做的就是
- 将
SimplePlugin.SimpleModel 中的模型定义注入sails.models
- 为带有
_config: { rest: true }的模型注入一个虚拟控制器
请注意,我发布的代码示例取自我正在处理的自定义 Sails 挂钩,并假定访问 sails 以及在 Sails 初始化的 loadHooks 阶段/@987654328 之前执行的代码示例@phase(比较:lib/app/load.js)。
1。注入模型定义
按照 Sails v0.10 中的 hints in the orm hook,您必须:
- 获取
api中定义的模型和适配器,将你的新模型合并到字典中
- 通过
sails.hooks.orm.normalizeModelDef 规范化模型定义
- 将标准化模型定义加载到 Waterline 中
- 通过
teardown卸载现有的适配器连接
- 重新初始化水线
- 通过
sails.hooks.orm.prepareModels(以前:sails.hooks.orm.exposeModels,更改为:8d96895662)将初始化的 Waterline 集合公开给帆和全局范围
因为您必须重新初始化 Waterline 并重新加载所有模型定义,所以我建议您收集所有模型定义以进行注入并将它们传递给注入函数一次。下面的示例代码反映了这一点。
...
function injectPluginModels(pluginModels, cb) {
// copy sails/lib/hooks/orm/loadUserModules to make it accessible here
var loadUserModelsAndAdapters = require('./loadUserModules')(sails);
async.auto({
// 1. load api/models, api/adapters
_loadModules: loadUserModelsAndAdapters,
// 2. Merge additional models, 3. normalize model definitions
modelDefs: ['_loadModules', function(next){
_.each(additionModels, function(aditionModel) {
_.merge(sails.models, additionalModel);
});
_.each(sails.models, sails.hooks.orm.normalizeModelDef);
next(null, sails.models);
}],
// 4. Load models into waterline, 5. tear down connections, 6. reinitialize waterline
instantiatedCollections: ['modelDefs', function(next, stack){
var modelDefs = stack.modelDefs;
var waterline = new Waterline();
_.each(modelDefs, function(modelDef, modelID){
waterline.loadCollection(Waterline.Collection.extend(modelDef));
});
var connections = {};
_.each(sails.adapters, function(adapter, adapterKey) {
_.each(sails.config.connections, function(connection, connectionKey) {
if (adapterKey !== connection.adapter) return;
connections[connectionKey] = connection;
});
});
var toTearDown = [];
_.each(connections, function(connection, connectionKey) {
toTearDown.push({ adapter: connection.adapter, connection: connectionKey });
});
async.each(toTearDown, function(tear, callback) {
sails.adapters[tear.adapter].teardown(tear.connection, callback);
}, function(){
waterline.initialize({
adapters: sails.adapters,
connections: connections
}, next)
});
}],
// 7. Expose initialized models to global scope and sails
_prepareModels: ['instantiatedCollections', sails.hooks.orm.prepareModels]
}, cb);
};
...
将允许您:
// Read your plugins
...
var pluginModels = // Get all the plugin models
injectPluginModels(pluginModels, function(){
// Plugin models now available via global[pluginModel.globalId] and sails.models[pluginModel.identity]
});
2。注入控制器
对于应该通过蓝图方法公开的每个模型,您必须:
- 创建具有匹配标识和启用蓝图的控制器定义
- 将控制器保存到
sails.controllers[controllerId]
- 将控制器保存到
sails.hooks.controllers.middleware[controllerId]
Sails MiddlewareRegistry 将自动拾取在这些对象中找到的控制器。
function mountBlueprintsForModels(pluginModels) {
_.each(pluginModels, function(pluginModel){
var controller = _.cloneDeep(pluginModel);
controller._config = { rest: true };
var controllerId = pluginModel.identity;
if (!_.isObject(sails.controllers[controllerId])) {
sails.controllers[controllerId] = controller;
}
if (!_.isObject(sails.hooks.controllers.middleware[controllerId])) {
sails.hooks.controllers.middleware[controllerId] = controller;
}
});
}
3。在行动
// E.g. in /api/hooks/plugins/index.js
/*
* Module dependencies
*/
var async = require('async'),
_ = require('lodash'),
waterline = require('waterline');
module.exports = function(sails) {
// injectPluginModels and mountBlueprintsForModels defined here
...
return {
initialize: function(cb) {
sails.after('hook:orm:loaded', function() {
yourNiftyPluginLoader(function(err, plugins) {
// assuming plugin.models holds array of models for this plugin
// customize for your use case
var pluginModels = _.pluck(plugins, 'models');
injectPluginModels(pluginModels, cb);
mountBlueprintsForModels(pluginModels);
});
});
}
}
}