2014-04-25 155 views
0

首先,對一個完整的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不工作。

我試圖尋找,但我不知道,如果問題是特定的方式來處理流星集合或我應該添加屬性爲JavaScript對象或成才完全無關的方式(範圍等)

我簡化了我的問題,試圖瞭解發生了什麼,我的真正的問題顯然是一個模板循環按:

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

感謝

回答

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(),或重複上面的行將其重置爲查詢集的開頭。

希望有幫助。

+0

非常感謝Hosts.update做的竅門,我將不得不再次閱讀這篇詳細的文章幾次才能完全理解。 – Purplefish32