具有异步getter的Mongoose虚拟字段

时间:2017-06-12 18:50:46

标签: node.js mongoose mongoose-schema

我有一个项目模型,它是一个虚拟字段来引用股票徽章。

'use strict';

const mongoose = require('mongoose');
const mongooseHidden = require('mongoose-hidden')();
const Badge = mongoose.model('Badge');

const validateProperty = function(property) {
  return (property.length);
};

const Schema = mongoose.Schema;

const ItemSchema = new Schema({
  itemCode: {
    type: Number,
    index: {
      unique: true,
      sparse: true // For this to work on a previously indexed field, the index must be dropped & the application restarted.
    },
    required: true
  },
  itemName: {
    type: String,
    uppercase: true,
    trim: true
  },
  barcode: {
    type: String,
    trim: true
  },
  category: {
    type: Schema.Types.ObjectId,
    ref: 'Category'
  },
  subCategory: {
    type: Schema.Types.ObjectId,
    ref: 'SubCategory'
  },
  updated: {
    type: Date
  },
  created: {
    type: Date,
    default: Date.now
  },
  status: {
    type: String,
    enum: [
      'active', 'inactive', 'removed'
    ],
    default: 'active'
  }
}, {id: false});

ItemSchema.virtual('badges').get(function() {
  return this.getAvailableBadges();
});

ItemSchema.methods.getAvailableBadges = function() {
  Badge.find({
    item: this._id
  }, (err, badges) => {
    if (badges) {
      return badges;
    } else {
      return [];
    }
  });
};

ItemSchema.set('toJSON', {virtuals: true});
ItemSchema.set('toObject', {virtuals: true});

ItemSchema.plugin(mongooseHidden, {
  hidden: {
    _id: false,
    __v: true
  }
});

mongoose.model('Item', ItemSchema);

批量模型如下

'use strict';

const mongoose = require('mongoose');
const mongooseHidden = require('mongoose-hidden')();

const validateProperty = function(property) {
  return (property.length);
};

const Schema = mongoose.Schema;

const BadgeSchema = new Schema({
  item: {
    type: Schema.Types.ObjectId,
    ref: 'Item'
  },
  qty: {
    type: Number,
    validate: [validateProperty, 'Please enter Quantity !']
  },
  purchasingPrice: {
    type: Number,
    validate: [validateProperty, 'Please enter purchasingPrice !']
  },
  sellingPrice: {
    type: Number,
    validate: [validateProperty, 'Please enter sellingPrice !']
  },
  updated: {
    type: Date
  },
  created: {
    type: Date,
    default: Date.now
  },
  status: {
    type: String,
    enum: [
      'active', 'inactive', 'removed'
    ],
    default: 'active'
  }
});

BadgeSchema.plugin(mongooseHidden, {
  hidden: {
    _id: false,
    __v: true
  }
});

mongoose.model('Badge', BadgeSchema);

项目的徽章虚拟字段没有填充。

我们如何使用异步getter方法

我已经发布了一些控制台日志语句,发现getAvailableBadges正在获取数据。

我需要通过express发送带有虚拟字段值的json对象。我该怎么做?

2 个答案:

答案 0 :(得分:1)

我所做的是创建虚拟财产

ItemSchema.virtual('badges', {
  ref: 'Badge',
  localField: '_id',
  foreignField: 'item'
});

填充它
{
   path: 'badges',
   select: [
     'qty', 'purchasingPrice', 'sellingPrice'
   ],
   options: {
     sort: {
       'created': -1
     }
   }
}

答案 1 :(得分:0)

嗯,操作是异步的,所以你必须等待回调才能触发。

您只能通过在回调中传递值来返回值(或者您可以在调用回调之前设置当前对象的值)。

我认为会是这样的:

ItemSchema.virtual('badges').get(function (callback) {
    Badge.find({ item: this._id }, callback);
};

然后你会像

一样使用它
item.badges(function (err, badges) {
    // do something with badges
});