Meteor:虽然尚未加载集合,但仍会显示模板

时间:2013-08-06 23:02:14

标签: javascript mongodb collections meteor publish-subscribe

嗨流星朋友们!

请注意:我正在使用Tom's router

所以我试图只在mongo集合准备就绪时显示我的模板,但由于某种原因它不起作用! :(

我首先关注此帖:LINK

所以我在server.js中有我的发布函数,我在路由器中订阅了这些函数,所以这里没有涉及Deps.autorun()(顺便说一句:这是正确的方法吗?Deps.autorun()不起作用适合我):

所以我有类似的东西:

'/myroute': function(bar) {
Meteor.subscribe("myCollection", bar, function() {
        Session.set('stuffLoaded', true);
    });
    return 'stuffPage';
}

在显示从“myCollection”加载的数据的模板中,我将会这样:

<template name="stuffPage">
    {{#if stuffLoaded}}
        <!-- Show the stuff from the collection -->
    {{else}}
        <p>loading!</p>
    {{/if}}
</template>

出于某种原因“加载!”永远不会显示。 此外,在几毫秒内,显示上一次显示相同模板的“旧数据”(但提供给发布功能的另一个“条形”值 - >不同的数据)。

这当然不是很好,因为在几毫秒内,用户可以看到旧数据,突然出现新数据。 为了避免这种“闪光”,我想显示“加载!”直到新数据加载但又一次:这对我不起作用! : - (

我做错了什么?

提前帮助你!

编辑:

好的,@ user728291提供的第一篇文章中的答案问题如下:

由于某种原因路由器的东西被称为Deps.autorun()之后......这里有什么问题? :((请注意:eventsLoaded == stuffLoaded。) 你们在哪里把你的De​​ps.autorun()用于订阅,换句话说:你的代码模型是什么?

my console.log

我实际上认为我的代码模型是完全错误的。那么如何根据路线进行不同的订阅(换句话说:基于当前显示的模板)?

AND:你把Deps.autorun()放在哪里?在router.add()函数里面?或者只是(Meteor.isClient)内部?

3 个答案:

答案 0 :(得分:2)

最好将订阅放在Deps.autorun中,并使用Session变量从路由器传递参数。此外,请确保在订阅运行之前将stuffLoaded设置为false。否则它只保留旧值。

'/myroute': function(bar) {
  if ( ! Session.equals( "bar", bar ) ) {
      Session.set( "stuffLoaded", false);  //subscription needs to be run
      Session.set( "bar", bar );  // this change will trigger Dep.autorun     
  }
  return 'stuffPage';
}

Deps.autorun ( function (){
  Meteor.subscribe("myCollection", Session.get( "bar" ), function() {
    Session.set("stuffLoaded", true);
  });
});

如果在第一次加载页面时没有得到想要的内容,则可能需要一些Session变量的初始默认值。

答案 1 :(得分:2)

我认为@ user728291的答案很明显,我只想补充说Meteor.subscribe会返回一个句柄,可以用来检查准备情况:

保留对句柄的引用

Deps.autorun(function() {
  stuffHandle = Meteor.subscribe(Session.get('bar'));
});

然后在模板中查看:

{{#if stuffHandle.ready}}
  ...
{{/if}}

Template.barTemplate.helpers({stuffHandle: stuffHandle});

通过会话控制它:

'/myroute': function(bar) {
   Session.set('bar', bar);
   return 'barTemplate';
 }

答案 2 :(得分:0)

首先,您可能会错过回调as demonstrated in this post的实际功能名称。

Meteor.subscribe("myCollection", bar, function onComplete() {
    Session.set('stuffLoaded', true);
});

这似乎是一种很好的做法。我通常不会错过使用这种方法的节拍。

其次,我不确定路线内的订阅是否运作良好?我宁愿做以下事情:

'/myroute': function(bar) {
    Session.set("myCollectionParam", bar)
    return 'stuffPage';
}

那么接下来最终看起来像这样:

 Meteor.subscribe("myCollection", Session.get("myCollectionParam"), function onComplete() {
    Session.set('stuffLoaded', true);
 });

(不确定哪种方式适合您,具体取决于您的发布功能):

 Meteor.subscribe("myCollection", {bar: Session.get("myCollectionParam")}, function onComplete() {
    Session.set('stuffLoaded', true);
 });
祝你好运!

修改

只提一下发布功能:

虽然Session.get(“myCollectionParam”)可以返回null,但您可以使用以下发布方法确保行为更多:

Meteor.publish("myCollection", function(myCollectionParam) {
   check(myCollectionParam, String); 
   return MyCollection.find({_id: myCollectionParam});
});