=====更新3(2019年4月4日)=========
我使用的是“猫鼬”:“ ^ 5.4.20”(在底部显示为测试该问题)
我需要先执行嵌套子元素的预保存,然后再执行父元素的预保存。 这是我的用例:
bank // parent
+---bank_account // 1st level child
| +----trans // 2nd level child
| +----trans
+---bank_account
+----trans
SCHEMAS
// a bank have multiple accounts, total has the total amount of money available in the whole bank
bank : {
total : {type:Number},
accounts : [ {type : bank_account} ]
}
// a bank account has a balance calculated with all its transfers
bank_account: {
balance : {type:Number},
transfers : [ {type:trans} ]
}
trans: {
amount : {type:Number}, // always positive
type : {type:String, enum:["credit", "debit"]}
}
HOOKS
//Bank
// sum all the accounts balance to have the total
bank.schema.pre('save'. function(next)
{
var self = this;
self.total = 0;
// calculate total iterating among all the accounts
for(let a in self.accounts)
{
self.total += self.accounts[a].balance;
}
return next();
})
//Bank Account
// calculate the balance considering the transfers
bank_account.pre('save'. function(next)
{
var self = this;
self.balance = 0;
// calculate balance iterating among transfers
for(let t in self.transfers)
{
var trans = self.transfers[t].balance;
if(trans.type == "credit")
{ self.balance += trans.amount; }
else // debit
{ self.balance -= trans.amount;}
}
return next();
})
当我这样做
bank.accounts[x].transfers.push(trans);
bank.save();
我希望在.save()
之后,bank.total
会有正确的总数,同时还要考虑我刚刚添加的新转帐。但事实并非如此...我如何使它工作?这个非常肮脏的解决方案可以执行bank.save()
2次,但这是一个非常肮脏的解决方案。
Documentation v.5.4.21说:
执行子文档的pre('save')和pre('validate')中间件 在顶级文档的pre('save')之前,但在顶级文档之后 文档的pre('validate')中间件。这是因为验证 在save()实际上是内置的中间件之前。
但这仅在只有一级孩子的情况下才是真实的。在我的情况下,我嵌套了孩子,并且正确的顺序仅保留在父级和(任何级别的)孩子之间……好像所有级别都将被展平。
我在REPL上做了一个片段,显示了问题所在