【问题标题】:Can't access Schema variables in Mongoose through static method无法通过静态方法访问 Mongoose 中的 Schema 变量
【发布时间】:2017-07-04 07:07:47
【问题描述】:

我正在完成一个教程,在 Express 和 Mongoose 中构建一个小型库数据库。在本教程中,每本书都可以具有几种状态之一,并且只能具有这些值中的一种。这是一个枚举。我通过在 BookInstance 模式中放置一个值数组来处理这个问题:

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

当我有一个实例时效果很好——我使用虚拟方法来获取这些值

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

如前所述,当我已经拥有一个实例时。

在创建 Schema 时,我将我的局部变量作为一个局部变量来访问:

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 实例,并在选择菜单中为用户提供状态选择,我将无法访问实例(除非我把它弄混,然后简单地创建一个来获取枚举值)。

我试着做一个静态函数

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

但它似乎不起作用。

做我想做的事情的最佳方法是什么? Mongoose中是否有“静态虚拟方法”之类的东西?

【问题讨论】:

    标签: node.js mongodb mongoose enums mongoose-schema


    【解决方案1】:

    自从我使用 MongoDB(当然还有 Mongoose)以来,已经有一段时间了,但是 static 方法无法访问实例。因此,您真的不应该在静态方法中使用this。此外,BookInstanceSchema 的实例似乎没有属性the_statuses(只是虚拟statuses)。从您的代码来看,您似乎可以访问 the_statuses 定义中的 BookInstanceSchema 变量。那么,为什么不直接使用呢?

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

    编辑:

    有关 JavaScript 中 this 的更多一般信息,请查看 this postMDN docs。简而言之,它在“严格”模式下的行为会发生变化,并且可以通过 Function 类的方法 .call.apply 进行操作,仅举几例。

    假设this 将引用调用给定方法的对象是正确的,因为这是默认行为。在我们的例子中,该对象是BookInstanceSchema.statics。但是,有一种情况是,Mongoose 在不同的上下文中调用statics 下的任何方法(我在这里假设),比如BookInstanceSchema,但它肯定不会从实例的上下文中调用,这就是方法所在的上下文BookInstanceSchema.methods 将被调用。需要注意的是,这完全是非标准的。 Mongoose 本质上是在模仿 OOP 概念,例如类方法和实例方法(分别为 Schema.staticsSchema.methods)。对于 Mongoose,我不确定 thisSchema.statics 上的方法中指的是哪个对象,但它肯定指的是 Schema.methods 上的实例对象。

    随着“类”语法变老(在 ES2015 中提出),更多的库可能会提供一种更“标准”的方式来定义类方法和实例方法(Sequelize 正在他们的下一个版本中解决这个问题)。此外,诸如类方法和实例方法之类的 OOP 概念可以在 JS 中实现,尽管略有不同。如果您有兴趣,this article 将阐明它在 Vanilla JS 中的工作原理,以及新类语法与旧函数原型语法对比的很好示例。

    【讨论】:

    • 完美运行。虽然我已经编程了很长时间,但它一直是用其他语言编写的,而且 Javascript 的“this”有时会让我感到困惑。在这种情况下,必须在实例内部才能引用“this”?据我了解,“this”指的是调用函数的对象/代码结构——但如果你在 Mongoose 中调用静态方法,它会被称为 from 什么东西?我想我可能正在混合和匹配 OOP(这是我习惯的)和 Javascript 世界,但我很想了解为什么您的解决方案有效。但无论如何,谢谢!
    • 很高兴它有帮助。是的,this 在 JS 中非常奇怪,在 Mongoose 的上下文中更是如此。将用一些细节编辑答案。
    猜你喜欢
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    • 2012-06-29
    • 2017-12-15
    • 2014-04-01
    • 1970-01-01
    • 2011-04-17
    相关资源
    最近更新 更多