我在node / express / mongoose中有一个场景,我有积累积分的用户,当积分超过某个阈值时,他们会升级" (想想基于点数的游戏)。
我在points字段上创建了一个自定义setter,用于检查值是否已更改,如果是,则尝试更新level字段。级别在另一个集合中定义,但在与用户文档关联时保存为简单的JSON对象(因此查询中的.lean())。为了提高效率,我这样做是为了虚拟场或人口。
问题:这实际上似乎并未更新用户级别'应该的时候。我究竟做错了什么?
// Define our user schema
var UserSchema = new mongoose.Schema({
...
points: {type: Number, default: 0, set: pointsChangeHandler},
level: {name: String, minPoints: Number, maxPoints: Number},
...
});
这个二传手看起来像这样:
function goodPointsChangeHandler(newValue) {
var self = this;
if (newValue != self.goodPoints) {
console.log('Point change detected.');
// Find level that corresponds with new point total
Level.findOne({
'minPoints': {$lte : self.goodPoints},
'maxPoints': {$gt : self.goodPoints}}, '-_id').lean().exec(function(err, level) {
if (self.goodLevel == undefined || self.goodLevel.rank != level.rank) {
console.log('Level changed.');
self.goodLevel = level;
}
return newValue;
});
}
return newValue;
}
答案 0 :(得分:3)
基于@laggingreflex的评论,我尝试在模型方法的范围内修改this
(即不在Level.findOne()
回调中,并且以 的方式进行的更改仍然存在没有明确的save()
电话。
另外,我有一个非常愚蠢的错误,我从 findOne`回调中返回newValue ..不知道我在想那里......
长话短说,这对于节点/快递/猫鼬专家来说可能是显而易见的,但是你可以修改除了你当前的setter方法之外的字段in,但是当你发现自己处于另一个异步方法的回调时,你必须做一个明确的save()
,否则你对this
的修改将不会被保留。
所以:
function myFieldSetterMethod(newValue) {
this.myField = "a";
this.myOtherField = "b";
return newValue;
// no save() necessary, this will update both fields
}
function myFieldSetterMethod(newValue) {
this.myField = "a";
SomeModel.findOne(..., function(err, doc) {
this.myOtherField = doc.somethingIWantFromThisDoc;
// now you'll need an explicit save
// this.save(...)
});
return newValue;
}