Underscore.js _.extend函数不在模式中定义时不复制mongoose模型属性?

为什么我不能使用下划线(_)扩展来更新模式定义中未定义属性的mongoose模型。 有没有办法解决这个问题?

节点型号:

var mongoose = require('mongoose') , Schema = mongoose.Schema var NodeSchema = new Schema({ label: {type : String, default : 'none'} }, { strict: false }) mongoose.model('Node', NodeSchema) 

节点控制器:

 var node = new Node(); node = _.extend(node, {"EXTENDNOTinSchema":"TRUE"}); console.log("extend: " + node); node.set("SETNOTinSchema","TRUE"); console.log("set: " + node); 

控制台输出:

 extend: { __v: 0, _id: 50bb05656880a68976000001, label: 'none' } set: { __v: 0, _id: 50bb05656880a68976000001, label: 'none' SETNOTinSchema: TRUE} 

发生这种情况是因为如果模式中没有东西,那么Mongoose不能使用' defineProperty ',并且像其他任何东西一样处理这个赋值。

所以首先,要清楚。

 node = _.extend(node, {"EXTENDNOTinSchema":"TRUE"}); 

与此相同:

 node['EXTENDNOTinSchema'] = 'TRUE'; 

在一般情况下,与此完全不同。

 node.set("SETNOTinSchema","TRUE"); 

诀窍是Mongoose很聪明,并且使用上面提到的defineProperty函数,它可以绑定一个函数来调用这样的事情:

 node['INSCHEMA'] = 'something'; 

但是对于不在模式中的事情,它不能这样做,所以赋值就像一个正常的赋值。

绊倒你的部分我认为是console.log正在做一些隐藏的魔法。 如果您查看文档 , console.log将调用传递给它的对象的inspect方法。 在Mongoose的情况下,模型不直接在模型对象上存储属性,它们存储在内部属性中。 当您使用defineProperty或call set分配给正在监视的属性时,它会将值存储在内部对象上。 当您log模型时, inspect打印出内部模型的内容,看起来好像模型值存储在对象上。

所以,当你这样做

 console.log(node); 

你真正看到的是

 console.log(node.somehiddenproperty); 

所以你的问题的答案是真的,如果你有一堆不在模式中的值,你不能使用_.extend 。 相反,只需使用set因为它无论如何都需要一个对象。

 node.set({"EXTENDNOTinSchema":"TRUE"});