2013-07-18 30 views
7

假設我有一個名爲GameStatus的Meteor集合。我有不同角色的用戶,但是我爲所有用戶發佈了GameStatus集合。我簡單地使用下面的服務器/ publications.coffee流星findOne查詢在一個模板助手中返回undefined。在其他模板助手中,同樣的查詢效果不錯

Meteor.publish 'gamestatus', -> 
    GameStatus.find() 

對於兩個角色(「S」和「B」)我有,當我使用下面的模板助手沒有問題的(在文件中定義客戶機/意見/ seller.coffee客戶端/視圖/ buyer.coffee

currentRound: -> 
    return GameStatus.findOne().currentRound 

對於這些我從來沒有碰到下面的錯誤。

Uncaught TypeError: Cannot read property 'currentRound' of undefined 

但另一個角色(「管理」),使用相同的模板助手(文件客戶端/視圖/ admin.coffee定義)給出了上述節目遺漏的類型錯誤。它適用,如果我改爲寫:

currentRound: -> 
    return GameStatus.findOne()?.currentRound 

我有點理解爲什麼這個工程。我認爲,當頁面被加載時,該集合首先不可用,然後它變爲可用。但爲什麼上面顯示的其他模板不會發生這種情況?

如果有人能幫助澄清這一點,我們將非常感激。

+0

當您訂閱集合時,在回調日誌中將某些內容記錄到控制檯,以便您知道它何時可用,並對該調用執行相同的操作以使其失敗。這樣你可以測試你的假設。 –

+0

@MDD你能舉個例子嗎?我應該記錄什麼來幫助我瞭解訂閱何時可用。看起來只是爲了這個特定的角色,他們最初是不可用的。 – Curious2learn

+0

你想爲你的訂閱https://gist.github.com/devonbarrett/b698c10cc427ee2c1811做這樣的事情,然後記錄類似於currentRound函數的東西,看看它是否在集合準備就緒之前被解僱了 –

回答

13

我相信,一個集合準備好的時候並不總是一致的,所以如果你想覆蓋所有的基礎,總是要編寫一個集合沒有準備好的情況。

有一種處理尚未準備好的集合的快捷方式,以及您可以在todos示例中找到的更復雜的解決方案。

快速和骯髒的解決方案看起來像這樣。

currentRound: -> 
    gameStatusrecord = GameStatus.findOne(); 
    if(gameStatusRecord) 
    gameStatusRecord.currentRound 

這將工作。在收集準備就緒之前,currentRound將返回null,並且您的模板將進行簡單渲染,並可能僅顯示當前一輪的空白。所以不是理想的用戶體驗,但不是一個大問題。

對於更復雜的解決方案,您可以檢查您訂閱的集合是否已準備好使用「就緒」功能進行查詢。如果一個集合還沒有準備好,你可以渲染一些其他的模板,比如「loading」,這樣可以保證在集合準備就緒之前不會調用currentRound助手。

例如,在待辦事項例如,客戶端訂閱的「列表」回收todos.js的線24:

var listsHandle = Meteor.subscribe('lists', function() { 

然後在待辦事項的80行定義了一個輔助功能的列表模板.js文件

Template.lists.loading = function() { 
    return !listsHandle.ready(); 
}; 

然後在todos.html線20名單模板,它不會嘗試提供任何模板,除非listsHandle已準備就緒。

<h3>Todo Lists</h3> 
{{#if loading}} 
    <div id="lists">Loading...</div> 
{{else}} 
    <div id="lists"> 
    {{#each lists}} 
    <!--etc.--> 
+0

謝謝你的建議。 – Curious2learn

相關問題