在Meteor中执行连接的正确方法是什么?

时间:2014-05-15 22:22:26

标签: templates meteor

我有两个集合,一个有一个user_id,它引用了一个users集合的_id字段。

我想查询所有用户一次,并使用下划线indexBy函数通过_id索引数组,然后在表中显示用户名而不是user_id

这样的事情:

Template.posts.users_by_id = function() {
    _.indexBy(Users.find().fetch(), '_id');
}

在模板中:

{{ users_by_id[user_id].name }}

但是,为表中的每一行调用users_by_id而不是一次。我已经尝试将_.indexBy的结果存储在Template.posts.user_by_id中,但后来我得到了Uncaught ReferenceError: Users is not defined

此外,我似乎无法访问名称密钥,只显示[object Object]

3 个答案:

答案 0 :(得分:0)

您似乎正在尝试优化效果......但您仍在使用自动发布?

如果是我,我会使用您想要的user_ids订阅Users集合,让服务器将该集合发布回客户端。由于这些用户实际上是在本地内存中,因此调用Users.find(user_id).fetch()。name应该花费很少的时间。而且它也是被动的,所以当你的收藏更新时,你的界面也会如此。

答案 1 :(得分:0)

如果您想将用户存储在字典中,您需要一本字典!

var users = {};
// var usersDep = new Deps.Dependency();

Template.posts.created = function() {
  users = _.indexBy(Users.find().fetch(), '_id');
  // usersDep.changed();
};

Template.posts.users_by_id = function() {
  // usersDep.depend();
  return users;
};

我在评论中添加了依赖关系管理。根据您初始化字典的位置,它可能或可能不是必需的,我现在不确定。

请注意,您只需返回用户而不是整个字典即可简化帮助程序:

Template.posts.user_by_id = function() {
  return users[this.user_id];
};


鉴于您订阅的所有用户对象已经在非常有效的Minimongo中,我建议采用直接方法:

Template.posts.user_name = function() {
  return Users.findOne(this.user_id).name;
};

一方面你有一个Minimongo查找而不是普通对象查找,但另一方面你不需要额外的字典内存,你不需要时间来填充和索引它,你不会遇到反应问题。如果此处的优化对您的应用程序至关重要,请尝试这两种方法并比较它们的渲染时间。

答案 2 :(得分:0)

这是Meteor的典型连接模式。使用查询执行连接。

<template name="users">
  {{#each users}}
    {{> user}}
  {{/each}}
</template>

<template name="user">
  {{#with user}}
    {{name}}
  {{/with}}
</template>

Template.users.helpers({
  users: function() {
    SomeCollection.find();
  }
});

Template.user.helpers({
  user: function() {
    return Users.findOne(this.user_id);
  }
});