2017-07-03 66 views
0

我正在通过教程,在Express和Mongoose中构建一个小型库DB。在本教程中,每本书可以具有几种状态之一,并且只有其中一种值。这是一个枚举。我通过将值的数组中的BookInstance模式处理这样的:无法通过静态方法访问Mongoose中的架构变量

var the_statuses = ['Available', 'Maintenance', 'Loaned', 'Reserved']; 

时,我有一个实例,它工作得很好 - 我用一个虚拟的方法来获取这些值

BookInstanceSchema 
    .virtual('statuses') 
    .get(function() { 
     return the_statuses; 
    }); 

当我如上所述,已经有一个实例。

和创建访问我的本地变量,以及架构,局部变量时:

var BookInstanceSchema = Schema({ 
    book: { type: Schema.ObjectId, ref: 'Book', required: true }, //reference to the associated book 
    imprint: {type: String, required: true}, 
    status: {type: String, required: true, enum: the_statuses, default: 'Maintenance'}, 
    due_back: {type: Date, default: Date.now}, 
}); 

但是,如果我想简单地直接从架构得到枚举值什么,而是从的架构?也就是说,如果我想创建,在这种情况下,一个BookInstance实例,并提供用户在选择菜单中的状态选择,我将无法访问实例(除非我kludge它并简单地创建一个来获取枚举值)。

我试图使静态函数

BookInstanceSchema.statics.getStatuses = function() { 
    return this.the_statuses; 
}; 

但它似乎并没有工作。

做我想做的事情的最佳方式是什么?在Mongoose中是否有这样的“静态虚拟方法”?

回答

1

由于我使用了MongoDB(和Mongoose,很明显),这已经有点儿了,但static方法不能访问实例。因此,你真的不应该在静态方法中使用this。此外,似乎BookInstanceSchema的实例不具有属性the_statuses(只是虚拟的statuses)。从您的代码判断,看起来您可以访问BookInstanceSchema定义中的the_statuses变量。那么,为什么不直接使用它?

BookInstanceSchema.statics.getStatuses = function() { 
    return the_statuses; 
}; 

// Use like 
BookInstanceSchema.getStatuses(); 

编辑:

用于JavaScript上this的一般信息,请this postMDN docs。简而言之,它是在“严格”模式下的行为变化,并且可以通过函数类的方法.call.apply来操纵它,以举出一些奇怪之处。

假设this指的是调用给定方法的对象,因为这是默认行为。在我们的案例中,该对象将是BookInstanceSchema.statics。但是,有一种情况是Mongoose在不同的上下文(我在这里假设)调用statics下的任何方法,如BookInstanceSchema,但它肯定不会从实例的上下文调用,这就是BookInstanceSchema.methods上的方法将被调用的上下文需要注意的是,这完全是非标准的。猫鼬实质上模仿OOP概念,如类方法和实例方法(分别为Schema.staticsSchema.methods)。在Mongoose的情况下,我不确定哪个对象thisSchema.statics的方法中引用,但它肯定指的是Schema.methods上的实例对象。随着“类”语法变得越来越老(在ES2015中提出),更多的库可能会容纳更“标准”的方法来定义类方法和实例方法(Sequelize正在其下一版本中对此进行研究)。另外,类方法和实例方法等OOP概念在JS中是可以实现的,尽管有些不同。如果你有兴趣,this article将阐明Vanilla JS的工作原理,以及与旧的函数原型语法形成鲜明对比的新类语法的很好的例子。

+0

完美工作。虽然我已经编程了很长时间,但它已被用于其他语言,JavaScript的“this”有时会引发我的注意。在这种情况下,一个人必须在一个实例内引用“这个”?据我了解,'this'是指从中调用函数的对象/代码结构 - 但是如果您在Mongoose中调用静态方法,它会被称为_from_ something?我想我可能会混合和匹配OOP - 这是我习惯的 - 和JavaScript世界,但我渴望理解_如何解决您的解决方案。但无论如何,谢谢! – Cerulean

+0

很高兴帮助。是的,这在JS中非常奇怪,在猫鼬的背景下更是如此。将编辑一些细节的答案。 – Nindaff