2015-04-23 58 views
1

我在流星JS的應用程序有一個集合:流星JS:訪問MongoDB的時序影響了訪問的結果

MenuItems = new Mongo.Collection('menu_items'); 

在我的模板助手文件我訪問這個集合:

Template.admin_menu_items.helpers({ 

    menuItems: function(){ 
    //return items from DB 
    console.log('inside menuItems'); 

    snapshot = MenuItems.find().fetch(); 

    console.log(snapshot); 

    return snapshot; 

    }, 
}); 

然後在我的html模板文件中,我稱這個幫手:

{{#each menuItems}} 
    {{#each items}} 
    {{this}} 
    {{/each}} 

{{/each}} 

然後在我的模板呈現的助手回調se ction我再次訪問該集合:

Template.admin_menu_items.rendered = function(){ 

    console.log('Template.admin_menu_items.rendered'); 

    var snapshotRendered = MenuItems.find().fetch(); 
    // 
    console.log(snapshotRendered); 


} 

如果我刷新頁面,我得到了以下的輸出:

inside menuItems     admin_m...4d3e6ec (line 9) 
[]         admin_m...4d3e6ec (line 13) 
Template.admin_menu_items.rendered admin_m...4d3e6ec (line 36) 
[]         admin_m...4d3e6ec (line 40) 
inside menuItems     admin_m...4d3e6ec (line 9) 
[Object { _id="nHZBfwAt64dwiPjCB", items=[3]}] 

我想明白,問的是:爲什麼是它第一次調用到MenuItems.find().fetch()裏面的menuItems幫手和第一次調用MenuItems.find().fetch()裏面的模板呈現回調函數返回一個空的[]數組,當MenuItems集合裏面已經有文檔時???

是不是因爲我的模板和模板幫助文件是在文件的層次更深,因此早於通過實例化MenuItems可變我menu_item.js文件加載:

MenuItems = new Mongo.Collection('menu_items'); 

如何保證MongoDB將從最初的調用或訪問完成後返回正確數量的文檔?

非常感謝您

回答

1

這與訂閱和線上數據有關的更多與處理文件的加載順序有關。當您刷新頁面,你得到的模板性的第一和數據後,這樣的操作順序是這樣的:

  1. 模板開始建立本身沒有數據,所以助手用一個空數組運行
  2. 模板完成建設和渲染,但沒有數據它也有一個空數組
  3. 數據到達
  4. 助手被動地重新運行與新的數據,並返回一個全陣列

如果您需要渲染回調中的數據,則解決方案是阻止此模板在數據到達之前運行。您可以使用等待訂閱的路由器,或者通過檢查數據並只在項目數量不爲零時渲染模板,或者使用Template.subscribe函數並使用if語句守護模板,直到數據爲準備。

在一個側面說明,你可能想在你的助手返回find()的結果,而不是find().fetch(),它會工作同樣在{{#each}}塊,但更細粒度的反應性大火可以遍歷光標本身。除非你真的需要陣列。

1

我如何確保MongoDB的將返回的文件的權利數量從做它最開始的呼叫或訪問???

那麼,在流星的精神...... 你不知道。

關於流星的全部事情是反應性。您不希望等待數據到達以開始渲染。這意味着你的用戶會在看到一些動作之前在空白頁面上觀看一段時間,因爲頁面塊渲染,等待在黑暗中忘記的全部數據。

而是你去反應。您執行立即執行的reactive computations,然後每次更新其中的反應數據。助手是反應式計算,Meteor中的Mongo遊標是反應式數據。助手最初運行(可能沒有返回任何數據,因爲數據還沒有到達),然後每次有一些新數據進來。

編寫這些代碼時,必須考慮「沒有,沒有數據」的情況反應計算。例如,if(someCollection.findOne())將確保someCollection中至少有一個文檔。
在你的情況下,雖然Spacebars可以很好地處理遊標,但它可能並不真正有用。