nodejs / express / mongo让res.render等到数据库搜索完成后再加载

时间:2014-02-13 21:39:17

标签: javascript node.js mongodb express mongoose

我无法正确加载此表,因为在将所有信息传递到我的ejs模板之前加载页面。对所有这一切都很新,并感谢任何帮助!

我应该注意,ownitems是用户架构中的一组ID。

routes.js:

app.get('/profile/:username', function(req, res) {
    User.findOne({username: req.params.username}, function(err, user) {
        var newDocs = [];
        if (!user) {
            req.flash('profilemessage', 'No such user exists.');
        } else {
            user.owneditems.map(function(i) {
                Items.findById(mongoose.Types.ObjectId(i), function(err, idoc) {
                    newDocs.push("<tr><td>" + idoc.name + "</td><td>" + idoc.brand</td></tr>");
                });
            }); 
        }
        res.render('profile.ejs', {title: 'Profile', items: newDocs, message: req.flash('profilemessage')});
    });
});

Profile.ejs:

<!-- content -->
<div class="wrapper row2">
    <div id="container" class="clear">
    <section>
        <% if (message) { %>
            <h4><%= message %></h4>
        <% } %>
        <table id="owneditems" class="sortable">
            <tr><th>Name</th><th>Brand</th></tr>
        <% for(var i=0; i<items.length; i++) {%>
            <%- items[i] %>
        <% } %>
        </table>
    </section>
    </div>
</div>

<% include layoutBottom %>

这种类型的设置适用于我的另一页,我只是无法在这里工作。谢谢!

1 个答案:

答案 0 :(得分:0)

在加载信息之前呈现页面的原因是因为Items.findById是异步的。这意味着newDocs在传递给res.render时不会返回您期望的项目数组。

如果要使用Mongoose加载(数组)子文档,最好使用query#populate。此方法允许您一次性将user.owneditems数组中的项ID替换为实际的项目文档。

我认为这适用于您的情况:

app.get('/profile/:username', function(req, res) {
    User.findOne({username: req.params.username})
    .populate('owneditems')
    .exec(function(err, user) {
        var newDocs = [];
        if (!user) {
            req.flash('profilemessage', 'No such user exists.');
        } else {
            user.owneditems.forEach(function(i) {
                newDocs.push("<tr><td>" + i.name + "</td><td>" + i.brand</td></tr>");
            }); 
        }
        res.render('profile.ejs', {title: 'Profile', items: newDocs, message: req.flash('profilemessage')});
    });
});

另请注意,我使用forEach切换了地图(考虑到你的回调,这似乎是你想要的)