2013-10-20 49 views
1

我想要路由到一個頁面,如果存在的話,另一個如果不存在。但是,我不想訂閱整個集合(〜數千個),因爲我認爲它會影響性能。我該怎麼做呢?Meteor.js:如何限制訂閱時動態路由?

我嘗試過這樣的事情,但由於某種原因,Meteor在頁面加載中經過兩次路由器代碼,並在重定向到項目頁面之前短暫地閃爍錯誤頁面,我不希望發生這種情況。

這是我有:

router.coffee

to: (id)-> 
    Meteor.subscribe 'item', id 
    item = Items.findOne id 
    if item 
    # if the item exists, then redirect to it 
    Session.set 'currentItemId', id 
    'itemPage' 
    else 
    # if not, then redirect to the sorry page 
    'sorryPage' 

publications.coffee

Meteor.publish 'item', (id)-> 
    return Items.find({_id: id}) 

訂閱整個集合會影響性能,對不對?有沒有更容易的方法來檢查集合內的存在,而不訂閱它?我試圖做一個Meteor.call來檢查它的服務器端,但它沒有工作,並不理想(路由器等待服務器調用..)。有沒有一種「正確」的方式來做到這一點?

+2

你要求的功能是建立在鐵路路由器(http://www.paypertise.com/meteorjs/iron-router-tutorial)上,你應該考慮使用它。 – saimeunt

回答

1

你得到這個「閃爍」效果的原因可能是因爲你的路由器被實現爲被動的(我不確定這是否是一個正確的策略),並且因爲你使用的是Items.findOne,所以此方法無效一旦Meteor.subscribe所請求的數據到達Items集合,就立即計算當前值。

另外,請注意,只要計算得到重新計算,活動計算中的每個訂閱就會自動取消。但是,正如文檔中所聲稱的那樣(請看here),Meteor應該足夠聰明,可以檢測兩次訂閱相同數據集的時間,因此不應該有任何副作用。

如果我是你,我會考慮改變我的路由器的邏輯是這樣的:

Session.set('currentItemId', id); 
var status = Session.get('currentItemStatus');  
if (status === 'ready') 
    return 'itemPage'; 
if (status === 'missing') 
    return 'sorryPage'; 
return 'loadingPage'; // probably status === 'loading' 

,然後在該項目中的其他地方,我會做:

Deps.autorun(function() { 
    Session.set('currentItemStatus', 'loading'); 
    Meteor.subscribe('item', Session.get('currentItemId'), function() { 
     // onReady callback 
     var item = Items.findOne({_id:id}); 
     if (item) 
      Session.set('currentItemStatus', 'ready'); 
     else 
      Session.set('currentItemStatus', 'missing'); 
    }); 
}); 

請注意,如果currentItemId不改變,定義的計算Deps.autorun將不會失效,因此不會向用戶顯示不必要的loadingPage

+0

我最終切換到鐵路由器,但這是我問的問題的解決方案。謝謝! – Oliver