2012-11-29 123 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' }