【问题标题】:Pre hooks in Mongoose Model as ES6 ClassMongoose 模型中的预钩子作为 ES6 类
【发布时间】:2018-07-08 03:10:58
【问题描述】:

我已经定义了一个猫鼬模式和类,但是在预验证钩子中,this 上下文是空的。我收到TypeError: this.validateColor is not a function

bike.js

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

// Mongodb Object Model
// =============================================================================
let BikeSchema = new Schema({
    color: {
        type: String,
        required: true
    },
    wheels: {
        type: Number,
        required: true
    }
});

// Bike Class
// =============================================================================
class BikeClass {

    validateColor() {
        if(this.color !== 'blue' && this.color != 'red') {
            this.invalidate('Not a valid color');
        }
    }

    validateWheels() {
        if(this.wheels < 2 || this.wheels > 3) {
            this.invalidate('Not a valid number of wheels');
        }
    }
}

BikeSchema.loadClass(BikeClass);

// Do validation checks as API hooks
BikeSchema.pre('validate', next => {
    // Problem: this = {}
    this.validateColor();
    this.validateWheels();
    next();
});

module.exports = mongoose.model('Bike', BikeSchema);

index.js

const Bike = require('./bike.js');
const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/bikes');
const db = mongoose.connection;

// Connect to Mongo db
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
    console.debug('Connected to mongo successfully');
    let bike = new Bike();
    bike.color = 'red';
    bike.wheels = 1;
    bike.save()
    .catch(err => {
        console.error(err);
    })
});

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    如果您在其中某处引用 this,则不能在 Mongoose 钩子中使用箭头函数,因为箭头函数处理 this 的方式与老式函数表达式不同。

    From MDN: 箭头函数表达式的语法比函数表达式短,并且没有自己的 this、arguments、super 或 new.target。这些函数表达式最适合非方法函数,它们不能用作构造函数。

    我记得在 Mongoose 文档的某个地方读到,钩子只能有老式的函数表达式,但我在任何地方都找不到。

    无论如何,只需将你的钩子重写为这样的东西

    BikeSchema.pre('validate', function (next) {
      // Problem: this = {}
      this.validateColor();
      this.validateWheels();
      next();
    });
    

    附带说明一下,由于可能出现错误问题,您应该使用命名函数作为钩子函数,这样明天抛出错误时,您将确切知道代码在哪个钩子函数中失败。

    【讨论】:

    • 是的箭头功能。 :)
    猜你喜欢
    • 1970-01-01
    • 2017-04-18
    • 2023-02-18
    • 2021-04-19
    • 2016-04-06
    • 2021-03-01
    • 2020-10-14
    • 2017-01-16
    • 2014-05-21
    相关资源
    最近更新 更多