0

私はマングースから取得した項目のリストをそれぞれリスト オブジェクトを参照して持っていますが、テンプレートで item.list.user.username として使用できるように、各リストに関連付けられた item.list.user オブジェクトを何らかの方法で設定する必要があります。

Item.find().populate('list').exec(function(err, items){
  items.forEach(function(item){
    User.findById(item.list.user), function(err, user){
      item.list.user = user;
    });
  });

 //how to get back here from User.findById() so I can render?
 res.render('index', { items: items });
});
4

1 に答える 1

4

これにはいくつかの方法があります。主な問題は、テンプレートをレンダリングするときにデータが入力されると想定していることです。常にそうであるとは限りません。非同期関数を実行するときはいつでも、各関数呼び出しが完了するまで待機しない限り実行されないと想定することができ、常に想定する必要があります。

これは、データがレンダリング可能であることを確認する簡単な方法です。

Item.find().populate('list').exec(function (err, items) {
  var len = items.length
    , populatedItems = [];
  items.forEach(function(item, i){
    User.findById(item.list.user, function (err, user) {
      item.list = item.list.toObject();
      item.list.user = user;
      populatedItems.push(item);
      if (i + 1 === len) {
        res.render('index', { items: items });
      }
    });
  });
});

ただし、これはあまり効率的ではなく、不要なデータベース呼び出しを行います。私の意見では、理由付けするのも難しいです。

Item.find().populate('list').exec(function (err, items) {
  var itemMap = {}
  items.forEach(function (item, i) {
    // Map the position in the array to the user id
    if (!itemMap[item.list.user]) {
      itemMap[item.list.user] = [];
    }
    itemMap[item.list.user].push(i)
    item.list = item.list.toObject()
  });
  // Can pull an array of user ids from the itemMap object
  User.find({_id: {$in: Object.keys(itemMap)}}, function (err, users) {
    users.forEach(function (user) {
      itemMap[user._id].forEach(function(id) {
        // Assign the user object to the appropriate item
        items[id].list.user = user;
      })
    });
    res.render('index', { items: items });
  });
});

IRC とトラブルシューティングについてさらに話し合った後、以下は特定のケースの実際の例です。

Item.find().populate('list').exec(function (err, items) {
  var itemIds = [];
  items.forEach(function (item) {
    itemIds.push(item.list.user)
  });
  // Can pull an array of user ids from the itemMap object
  User.find({_id: {$in: itemIds}}, function (err, users) {
    var userMap = {}
    users.forEach(function (user) {
      userMap[user._id] = user
    });
    res.render('index', { items: items, userMap: userMap });
  });
});
于 2012-11-01T07:19:11.427 に答える