流星收集麻烦

时间:2014-04-25 13:46:14

标签: javascript collections meteor

首先,对不起是一个完整的javascript noob,我更像是一个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无效。

我尝试过搜索,但我不知道问题是否特定于meteor处理集合的方式,或者我应该将属性添加到javascript对象或者完全不相关的范围(范围等等)< / p>

我已经简化了我的问题,试图了解发生了什么,我的真正问题显然是在模板中循环:

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

由于

1 个答案:

答案 0 :(得分: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()来回放它,或者重复上面的行以将其重置为查询的开头集。

  4. 希望这有帮助。