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

时间:2012-12-02 07:49:47

标签: node.js mongoose underscore.js

为什么我不能使用下划线(_)扩展来更新未在模式定义中定义属性的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}

1 个答案:

答案 0 :(得分:7)

这种情况正在发生,因为如果模式中没有某些东西,那么Mongoose就不能使用“defineProperty”,这会像其他任何一样对待赋值。

首先,只是为了清楚。

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

与此相同:

node['EXTENDNOTinSchema'] = 'TRUE';

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

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

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

node['INSCHEMA'] = 'something';

但是对于那些不在模式中的东西,它不能这样做,所以赋值就像普通的赋值一样。

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

所以当你这样做时

console.log(node);

你真正看到的是

console.log(node.somehiddenproperty);

因此,您的问题的答案实际上是,如果您有一堆不在架构中的值,则无法使用_.extend。相反,只需使用set因为它无论如何都需要一个对象。

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