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

wro*_*coe 1 mongoose node.js 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)
Run Code Online (Sandbox Code Playgroud)

节点控制器:

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

控制台输出:

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

set: { __v: 0,
  _id: 50bb05656880a68976000001,
  label: 'none' 
  SETNOTinSchema: TRUE}
Run Code Online (Sandbox Code Playgroud)

log*_*yth 7

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

首先,要明确一点.

node = _.extend(node, {"EXTENDNOTinSchema":"TRUE"});
Run Code Online (Sandbox Code Playgroud)

与此完全相同:

node['EXTENDNOTinSchema'] = 'TRUE';
Run Code Online (Sandbox Code Playgroud)

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

node.set("SETNOTinSchema","TRUE");
Run Code Online (Sandbox Code Playgroud)

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

node['INSCHEMA'] = 'something';
Run Code Online (Sandbox Code Playgroud)

但是对于不在模式中的东西,它不能这样做,因此赋值就像普通赋值一样.

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

所以,当你这样做

console.log(node);
Run Code Online (Sandbox Code Playgroud)

你真正看到的是

console.log(node.somehiddenproperty);
Run Code Online (Sandbox Code Playgroud)

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

node.set({"EXTENDNOTinSchema":"TRUE"});
Run Code Online (Sandbox Code Playgroud)