1

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

节点型号:

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}
4

1 回答 1

7

发生这种情况是因为如果架构中没有某些内容,则 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或调用监视的属性时set,它将值存储在内部对象上。当您创建log模型时,会inspect打印出内部模型内容,使模型值看起来像是直接存储在对象上。

所以当你这样做时

console.log(node);

你真正看到的是

console.log(node.somehiddenproperty);

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

node.set({"EXTENDNOTinSchema":"TRUE"});
于 2012-12-04T03:58:33.377 回答