Meteor.js:限制订阅时如何动态路由?

时间:2013-10-20 22:48:59

标签: collections meteor router subscription

如果有东西存在,我正试图路由到一个页面,如果不存在则尝试路由到另一个页面。但是,我不想订阅整个集合(〜数千),因为我认为它会影响性能。我该怎么做?

我试过这样的事情,但由于某种原因,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来检查它的服务器端,但它没有工作,并不理想(路由器等待服务器调用..)。有没有“正确”的方法来做到这一点?

1 个答案:

答案 0 :(得分:1)

你获得这种“闪烁”效果的原因可能是因为你的路由器被实现为被动(我不确定这是一个正确的策略BTW),并且因为你正在使用Items.findOne,只要Meteor.subscribe请求的数据到达Items集合,此方法就会使当前计算失效。

另外,请注意,一旦计算重新计算,活动计算中的每个订阅都会自动取消。但是,正如文档中声明的那样(外观hereMeteor应该足够智能,以便检测您何时订阅两次相同的数据集,因此这不会产生任何副作用。

如果我是你,我会考虑将路由器逻辑更改为:

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