如何在sails.js中为所有模型添加实例方法?

10
我希望为所有的模型添加一个默认的toDisplay函数,它将使用元数据来对实例的属性/关联进行操作,使它们适合在UI中显示。例如:
Foo.findOne(someId)
  .exec(function(err, foo) {
    ...
    res.view({
      foo: foo.toDisplay(),
    });
  });

因此,我希望将此功能添加到所有模型中。我可以想象

Model.prototype.toDisplay = ... 

我需要解决问题,但不确定从哪里获取模型(需要长长的 require('waterline/..../model') 路径吗?),而且如果我有了模型,也不知道要把那段代码放在哪里。

请给予建议。


好的,让我们看看是否添加更多标签可以在40小时内获得超过12个观看次数(其中4个是我的)。 - umassthrower
2个回答

10

模型配置完全记录在SailsJS.org。@umassthrower指出,在config/models.js中添加实例方法会将其添加到所有模型中;他还观察到,这不是配置文件的预期用途。

你发现在Sails中这比Rails更具挑战性的原因是Ruby有真正的类和继承,而JavaScript只有对象。一个相当干净的模拟继承并从“基”对象扩展模型对象的方法是使用像Lodash的_.merge函数之类的东西。例如,您可以将基础模型保存在lib/BaseModel.js中:

// lib/BaseModel.js
module.exports = {

  attributes: {

    someAttribute: 'string',

    someInstanceFunction: function() {
      // do some amazing (synchronous) calculation here
    }

  }

};

然后在你的模型文件中,引入lodash并使用_.extend

Translated text:

然后在你的模型文件中,引入lodash并使用_.extend

// api/models/MyModel.js
var _ = require('lodash');
var BaseModel = require("../../lib/BaseModel.js");
module.exports = _.merge({}, BaseModel, {

  attributes: {

    someOtherAttribute: 'integer'

  }

};

您的基础模型属性将与MyModel合并,MyModel具有优先权。

在此处将第一个参数设置为空模型{}非常重要;_.merge对于发送的第一个对象是破坏性的,因此如果您只是执行_.merge(BaseModel, {...}),则基础模型将被修改。

另外,请记得要运行npm install lodash


这似乎是一个合理的方法,比将它们添加到config/models.js中更容易接受。我仍然需要为每个模型添加一行额外的代码,但至少只需要添加一次,然后就可以拥有这个结构了。我会尝试一下,谢谢! - umassthrower
我是个懒鬼,如果我想要给每个模型都添加一些东西,被迫在每个模型文件中添加相同的行真的让我很烦恼。对于我来说,这不是解决问题的方式,因为你仍然需要对每个单独的模型做些什么。 - Adam Pietrasiak

0
在Sails 0.x版本中,当模块加载器被加载时,您可以直接访问sails.models,但现在在1.x版本中尚未准备好。因此,我的解决方案是创建一个自定义钩子,它包装了sails.modules的loadModels函数。这可能不是最佳解决方案,但对我有效。希望对你也有用@adam-pietrasiak :) 当需要重复代码时,我也非常懒。

// provide this code in api/hooks/overrides.js or use another name, who cares

  
const _ = require('lodash');

module.exports = function (sails) {
    return {
        defaults: {},
        savedModelLoad: null,

        configure: function () {
            this.savedModelLoad = this.savedModelLoad || sails.modules.loadModels;
            sails.modules.loadModels = this.loadModelsAndApplyOverrides;
        },

        loadModelsAndApplyOverrides: function(cb){
            this.savedModelLoad(function (err, models) {
                const newModels = _.map(models, applyModelOverrides);

                cb(err, newModels);
            });
        }
    };
};

function applyModelOverrides(model) {
    return _.merge(model, {
      // do your custom stuff here
        attributes: {

            someAttribute: 'string',

            someInstanceFunction: function() {
                // do some amazing (synchronous) calculation here
            }

        }
    });
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接