【问题标题】:Custom constructor function in Mongoose schema/modelsMongoose 模式/模型中的自定义构造函数
【发布时间】:2012-12-22 10:17:30
【问题描述】:

大家好!

我如下定义了一个 Mongoose 模式并注册了一个模型 (InventoryItemModel)。有没有办法为模式创建自定义构造函数,这样当我从模型中实例化一个对象时,该函数将被调用(例如,从数据库中加载具有值的对象)?

var mongoose = require('mongoose')
  , Schema = mongoose.Schema

var InventoryItemSchema = new Schema({
    Sku : String
  , Quanity : Number
  , Description : String
  , Carted : []
  , CreatedDate  : {type : Date, default : Date.now}
  , ModifiedDate  : {type : Date, default : Date.now}
});

mongoose.model('InventoryItem', InventoryItemSchema);

var item = new InventoryItem();

我可以添加一些自定义构造函数,以便在实例化时从数据库中填充项目吗?

【问题讨论】:

  • 你能举一个具体的例子来说明你正在尝试做什么吗?
  • 嗨,我想创建一个库存管理。上面的对象代表一个项目。某些 API 会将项目推送到数据库中,在我的程序中,我希望模型在实例化对象时从数据库中加载一个项目。
  • 看看Mongoose对adding static constructor methods to models的支持。

标签: node.js mongoose


【解决方案1】:

根据你想走的方向,你可以:

1) 使用 Hooks

在模型初始化、验证、保存和删除时会自动触发挂钩。 这是“由内而外”的解决方案。 您可以在此处查看文档:

2) 为您的架构编写静态创建函数。

静态信息存在于您的模型对象上,可用于替换创建新模型等功能。如果您的 create 步骤有额外的逻辑,您可以自己在静态函数中编写。这是“由外而内”的解决方案:

【讨论】:

  • #2(静态创建函数)具体是怎么做的? Mongoose 指南中似乎没有任何示例,仅添加 myschema.static.create 函数似乎没有任何作用。
  • 该链接 (#statics) 向您展示了如何编写静态数据。只需编写您自己的静态(createNew 或其他东西),它会在创建时通过您希望它通过的任何逻辑。
  • 抱歉,我把方法和静态混淆了。
  • 我也做了2),但我认为该方法不应该命名为create,因为它与Model.create 冲突。不确定重写该方法是否有害,但我想使用其他名称更安全(如makeinitialize 等)
【解决方案2】:

这是来自@hunterloftisanswer 的选项#2 的实现。

2) 为您的架构编写一个静态创建函数。

someSchema.statics.addItem = function addItem(item, callback){
//Do stuff (parse item)
 (new this(parsedItem)).save(callback);
}

当您想从 someSchema 创建新模型时,而不是

var item = new ItemModel(itemObj);
item.save(function (err, model) { /* etc */ });

这样做

ItemModel.addItem(itemObj, function (err, model) { /* etc */ });

【讨论】:

    【解决方案3】:

    我自己遇到了这个问题,写了一个猫鼬插件来帮助解决你的问题

    var mongoose = require('mongoose')
      , Schema = mongoose.Schema
      , construct = require('mongoose-construct')
    
    var user = new Schema({})
    user.plugin(construct)
    
    user.pre('construct', function(next){
        console.log('Constructor called...')
        next()
    })
    
    var User = mongoose.model('User', user)
    var myUser = new User(); // construct hook will be called
    

    这里是 repo(也可以在 npm 上找到):https://github.com/IlskenLabs/mongoose-construct

    【讨论】:

    • 这是一个巧妙的想法。它可以捕获传递给模式构造函数的参数吗?例如,如果我想在创建时调用var myUser = new User({foo:'bar'}) 来配置用户的某些属性,有没有办法从您的预构造函数中访问该“foo”?
    • @Victorb 老实说,我什至不记得它是如何工作的,并且严重怀疑它是否适用于最新版本的猫鼬。对不起!
    • @Victorb 仔细看了一遍,抱歉,在不破坏东西的情况下,任何钩子都不可能做到这一点。我会创建一个包装类,它接受参数并在后台初始化一个猫鼬模型
    【解决方案4】:

    @hunterloftis 为我提供了我需要的答案。现在,将近 6 年多后,这是我为其他人提供的解决方案。

    InventoryItemSchema.static( 'new', function( that )
    {
        let instance = new InventoryItemSchema();
        Object.assign( instance, that );
        return instance;
    });
    

    或者作为单线(不利于调试)

    InventoryItemSchema.static( 'new', function( that )
    {return Object.assign( new InventoryItemSchema(), that );});
    

    无论哪种方式,您都想拥有

    let inventoryItem = new InventoryItemSchema({...});
    

    你将拥有

    let inventoryItem = InventoryItemSchema.new({...});
    

    【讨论】:

      【解决方案5】:

      您需要导出。这是一个例子:

      import mongoose from "mongoose";
      
      let  Schema = mongoose.Schema;
      
      
      let restaurentSchema = new Schema({
        name : String
      })
      
      //export
      
      module.exports = mongoose.model("Restaurent", restaurentSchema)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-12
        • 2018-12-11
        • 2018-01-29
        • 1970-01-01
        • 2018-06-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多