【问题标题】:Meteor collection trouble流星收集麻烦
【发布时间】:2014-04-25 22:09:05
【问题描述】:

首先,对不起,我是一个完整的 javascript 菜鸟,我更像是一个 PHP 人,正在测试流星框架。

我正在尝试遍历对象集合并尝试从另一个集合中添加属性:

Template.host.hosts = function() {
    var hosts = Hosts.find();

    hosts.forEach(function(host) {
        host.lastPing = Pings.findOne({id: host.id}, {sort: {timestamp : -1}});

        // This works fine
        // console.log(host.lastPing.id);
    });

    for (host in hosts) {

        // This results in "TypeError: Cannot read property 'id' of undefined"
        console.log(host.lastPing.id);
    }

    return hosts;
};

我不明白为什么第二个 console.log 不起作用。

我尝试过搜索,但我不知道问题是特定于流星处理集合的方式,还是我应该向 javascript 对象添加属性或完全不相关的方式(范围等...)

我已经简化了我的问题以试图了解正在发生的事情,我真正的问题显然是按照以下方式在模板中循环:

{{#each hosts}}
    {{this.lastPing.id}}
{{/each}}

谢谢

【问题讨论】:

    标签: javascript collections meteor


    【解决方案1】:

    三件事:

    1. MongoDB 和 Meteor id 存储在 _id 而不是 id

    2. 在您的forEach 方法的上下文中,host 迭代由Hosts.find() 返回的查询集,但它实际上并没有让您访问文档本身。本质上,它是 MongoDB 中信息的副本,而不是数据库中的文档。

      更新实际文档的正确(也是唯一)方法是使用Collection.update 方法:

      Hosts.update({_id: host._id}, {$set: {lastPing: Pings.findOne({id: host.id}, {sort: {timestamp : -1}}) }});
      

      (请注意,您只能在客户端上通过_id 进行更新,这就是我在这里使用的原因,而您可以在服务器上提供任何查询。)

    3. hosts 对象是一个光标,而不是一个数组。这意味着当您使用for host in hosts 时,您实际上是在遍历游标对象的属性(继承自原型)而不是主机数组,并且它们都没有 id 属性。完成这项工作的一种方法是获取查询集并将其放入hosts,如下所示:

      var hosts = Hosts.find().fetch();
      

      或者,您可以坚持使用光标并再次使用 forEach,尽管您必须使用 hosts.rewind() 将其倒回,或者重复上面的行以将其重置为查询集的开头。

    希望对您有所帮助。

    【讨论】:

    • 非常感谢 Hosts.update 成功了,我将不得不重新阅读这篇详细的帖子几次才能完全理解。
    猜你喜欢
    • 2012-11-20
    • 2015-01-20
    • 2015-07-22
    • 2018-06-22
    • 1970-01-01
    • 2013-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多