2017-08-16 65 views
0

在Mongoose应用程序中,我可以使用虚拟函数通过ref查找子对象。节点Mongoose虚拟属性返回符合条件的子项

我有一个问题是,给定一个父对象与许多具有两个日期(start_date,end_date)的子对象的ref关系。

父对象:

{ 
    "id": 12345, 
    "children": [...] // <= A virtual property to the child objects below. 
} 

子对象

[{ 
    "parent": 12345, 
    "start_date": "2016-01-01", 
    "end_date": "2016-02-01" 
}, 
{ 
    "parent": 12345, 
    "start_date": "2016-02-02", 
    "end_date": "2016-03-01" 
}] 

理想情况下,我想有一个叫做当前的虚拟属性,返回子对象在当前日期落在start_date和end_date之间。

举个例子,如果今天是“2016年2月20日”,我想结果是这样的:

{ 
    "id": 12345, 
    "children": [...], // <= A virtual property to the child objects below. 
    "current": { 
     "parent": 12345, 
     "start_date": "2016-02-02", 
     "end_date": "2016-03-01" 
    } 
} 

我试图寻找了虚拟功能的子属性,但它似乎是因为它是一个承诺,它总是返回null。我不确定是否有更简单的方法来做到这一点,但我真的很感激任何想法。

这是我试过的,但总是返回null。即使我登录到控制台,结果显示在那里:

ParentSchema 
.virtual('current') 
.get(function() { 
    var result = null; 
    ChildModel.find({parent: this._id}, function (err, results) { 
     // ... some logic here to find the correct item. (Omitted for brevity). 
     result = foundItem; 
    }); 
    return result; 
}) 

非常感谢!

回答

1

还记得猫鼬操作是异步的,所以你需要等待他们的回调被调用之前得到结果。

ParentSchema.virtual('current').get(function() { 
    var result = null; 
    ChildModel.find({parent: this._id}, function callback(err, children) { 
     // ... 
     result = child; 
    }); 
    // by the time it reaches this point, the async function^will not yet be finished -- so result will always be null 
    return result; 
}) 

(1)要使用虚拟属性,您必须返回Promise而不是值。

ParentSchema.virtual('current').get(function() { 
    var self = this; 
    return ChildModel.find({ parent: self._id }, function (err, children) { 
     // ... 
     self.current = child; 
    }); 
}) 

你可以这样使用它像

parent.current.then(function() { 
    console.log(parent.current); 
}).catch(function (err) { 
    // ... 
}) 

(2)我认为这是更好地做到使用方法来代替。

ParentSchema.methods.getCurrent(function (callback) { 
    var self = this; 
    ChildModel.find({ parent: self._id }, function (err, children) { 
     if (err) return callback(err); 
     // ... 
     self.current = child; 
     callback(); 
    }); 
}); 

你可以这样使用它像

parent.getCurrent(function (err) { 
    console.log(parent.current); 
}) 
+0

很好的概述。非常感谢! –