【问题标题】:how to call default blueprint actions in a custom overridden one?如何在自定义覆盖中调用默认蓝图操作?
【发布时间】:2015-03-28 01:27:48
【问题描述】:

SailsJS 提供默认的蓝图操作,例如查找、更新、创建等。

我需要覆盖其中的一些以适应特定的业务目的。但是,我想添加它们,而不是简单地覆盖它们。如何在覆盖操作中调用默认蓝图操作。

例如update可以更新模型的记录。

update 

除了更新模型的记录之外,我还想让 update 做更多的事情。在我的自定义更新方法中,我不想重复默认更新。我该怎么做?

【问题讨论】:

    标签: sails.js


    【解决方案1】:

    您应该查看sailsjs 中的lifecycle callbacks。因此,例如,您可以使用beforeUpdatebeforeCreate 生命周期回调在模型中做更多事情:

    var bcrypt = require('bcrypt');
    
    module.exports = {
    
      attributes: {
    
        username: {
          type: 'string',
          required: true
        },
    
        password: {
          type: 'string',
          minLength: 6,
          required: true,
          columnName: 'encrypted_password'
        }
    
      },
    
    
      // Lifecycle Callbacks
      beforeCreate: function (values, cb) {
    
        // Encrypt password
        bcrypt.hash(values.password, 10, function(err, hash) {
          if(err) return cb(err);
          values.password = hash;
          //calling cb() with an argument returns an error. Useful for canceling the entire operation if some criteria fails.
          cb();
        });
      }
    };
    

    【讨论】:

    • 我试过 beforeUpdate 生命周期回调。但是当我发布到模型时,例如POST /abc 其中 Abc 是模型,beforeUpdate 也是触发器。这是为什么呢?
    • 我认为不应该。你也有beforeCreate 回调吗?也许您正在那里编辑和保存模型而不使用触发beforeUpdate的回调?
    【解决方案2】:

    复制所有内容

    PROJECT-ROOT\node_modules\sails\lib\hooks\blueprints\actions
    

    PROJECT-ROOT\config\blueprints
    

    确保 findOne.js 是小写的。您需要修改每一项以引用actionUtil.js 的位置。您现在可以随心所欲地修改这些内容,而无需重新发明轮子。

    【讨论】:

    • 如何使这些覆盖操作因不同模型而不同?
    • 视情况而定。如果模型之间存在巨大差异,那么您可能根本不想使用蓝图。在您的控制器中,您只需添加一个方法来覆盖单个操作,而其余部分保持不变。因此,对于用户模型,我可以在该控制器上创建一个“更新”方法,它将仅覆盖该蓝图并保持其余部分不变。但是,如果您的差异很小,那么您可以在蓝图文件中识别您的模型并根据需要进行调整。
    • 我已经尝试过您的解决方案,但无法成功。在提升过程中,我收到错误A hook ('userconfig') failed to load!
    • gist.github.com/mphasize/e9ed62f9d139d2152445 beforeBlueprint 策略可以理解
    【解决方案3】:

    我刚刚遇到了同样的问题,并找到了一种不同的方法来解决它。如果将来有人遇到同样的问题,它可能会有所帮助。我最后做的是在控制器中重新编写动作,在我的例子中是add,然后在里面做了一些事情之后,调用了默认蓝图的动作。 所以,我的代码如下所示:

    add: function (req, res) {
        if (xxx) {
            // I need to do something only when the condition above is met
            Section.count({xxx: xxx)}).exec(function (error, count) {
                if (error) {
                    return res.json(500, {error: 'There was an error while trying to run query'});
                }
                //I do what I have to do
                return sails.hooks.blueprints.middleware.add(req, res);
            });
        } else {
            //I just return the default blueprint's action
            return sails.hooks.blueprints.middleware.add(req, res);
        }
    }
    

    因此,基本上,默认蓝图函数存储在: sails.hooks.blueprints.middleware

    【讨论】:

    • 这回答了我的问题。谢谢
    • 为你是冠军点赞 :)
    • 考虑到sails.hooks.blueprints.middleware中的所有函数都有小写名称(例如findone
    • 假设在我的控制器中我调用sails.hooks.blueprints.middleware.findone(req, res); 我怎样才能得到模型对象之前被发送回客户端?
    • sails.hooks.blueprints.middleware 似乎没有这些(find、findone、findOne 等)。知道他们被转移到哪里了吗?解决方法是require(`${sails.config.appPath}/node_modules/sails/lib/hooks/blueprints/${action}`),但一点也不理想...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    相关资源
    最近更新 更多