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)
这种情况正在发生,因为如果模式中没有某些东西,那么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)