2012-11-29 99 views
9

所以我知道如何让一个单一的虚拟属性,如猫鼬文档指出:获取对象数组中每个嵌套对象的虚拟属性?

PersonSchema 
.virtual('name.full') 
.get(function() { 
    return this.name.first + ' ' + this.name.last; 
}); 

但如果我的架构是什么:

var PersonSchema = new Schema({ 
    name: { 
     first: String 
    , last: String 
    }, 

    arrayAttr: [{ 
     attr1: String, 
     attr2: String 
    }] 
}) 

而且我想添加一个虚拟属性的arrayAttr中的每个嵌套对象:

PersonSchema.virtual('arrayAttr.full').get(function(){ 
    return attr1+'.'+attr2; 
}); 

让我知道我是否错过了这里的东西。

回答

0

首先,你应该写

this.some_attr,而不是some_attr

而且你不能存取权限this.attr因为有arrayAttr。所以,你可以例如做:

this.arrayAttr[0].attr1 + "." + this.arrayAttr[0].attr2 

这是不是安全的,因为arrayAttr可以为空

21

您需要定义的attrArray元素的独立架构和虚拟属性添加到该架构。

var AttrSchema = new Schema({ 
    attr1: String, 
    attr2: String 
}); 
AttrSchema.virtual('full').get(function() { 
    return this.attr1 + '.' + this.attr2; 
}); 

var PersonSchema = new Schema({ 
    name: { 
     first: String 
    , last: String 
    }, 
    arrayAttr: [AttrSchema] 
}); 
+1

有没有办法做到这一点无需额外的架构?或者我应该说,额外的嵌入架构 –

+0

@deusj不是我知道的,没有。 – JohnnyHK

+0

很酷,谢谢你的回答 –

4

当然,你可以定义一个额外的模式,但猫鼬已经为你做了这个。

它存储在

PersonSchema.path('arrayAttr').schema 

所以,你可以将它添加到这个模式

PersonSchema.path('arrayAttr').schema.virtual('full').get(function() { 
    return this.attr1 + '.' + this.attr2 
}) 
+0

如果'arrayAttr'是一个对象数组。这是指哪个对象?或者'full'现在是'arrayAttr'内每个对象的新属性或关键字? –

+1

full是每个arrayAttr对象上的新虚拟属性。 –

-1

我最喜欢的解决方法是直接引用嵌套模式设置一个虚拟的。

PersonSchema.paths.arrayAttr.schema.virtual('full').get(function() { 
    return this.attr1 + '.' + this.attr2; 
}); 

重要的是还要注意的是默认情况下不会通过猫鼬模式返回虚拟。因此,确保在嵌套架构上设置字符串化属性。

var options = { virtuals: true }; 
PersonSchema.paths.arrayAttr.schema.set('toJSON', options); 
0

如果你想从这里所有的数组元素的计算值是一个例子:

const schema = new Schema({ 
    name:   String, 
    points: [{ 
     p:  { type: Number, required: true }, 
     reason: { type: String, required: true }, 
     date: { type: Date, default: Date.now } 
    }] 
}); 

schema.virtual('totalPoints').get(function() { 
    let total = 0; 
    this.points.forEach(function(e) { 
     total += e.p; 
    }); 
    return total; 
}); 

User.create({ 
    name: 'a', 
    points: [{ p: 1, reason: 'good person' }] 
}) 

User.findOne().then(function(u) { 
    console.log(u.toJSON({virtuals: true})); 
}); 

返回到:

{ _id: 596b727fd4249421ba4de474, 
    __v: 0, 
    points: 
    [ { p: 1, 
     reason: 'good person', 
     _id: 596b727fd4249421ba4de475, 
     date: 2017-07-16T14:04:47.634Z, 
     id: '596b727fd4249421ba4de475' } ], 
    totalPoints: 1, 
    id: '596b727fd4249421ba4de474' }