为什么我的流星模板不被反应性渲染?

时间:2013-11-03 23:08:02

标签: javascript meteor

我有一个像这样的模板助手

Template.index.allUpcomingGames = function() {
    return Games.find({date: {$gte: new Date()}}, {sort: {date: 1}});
};

因此,如果我正确阅读文档,则只要此查询结果发生更改,就应重新呈现模板。

我看到的实际行为是,当我第一次加载页面(空的minimongo缓存)时,模板没有结果。当检测到增量更改并且强制重新呈现模板时,项目会神奇地出现,因此可能在查询返回之前发生初始页面加载,并且随后不会像我期望的那样被动地重新呈现。我究竟做错了什么?管理查询模板依赖关系的最佳实践是什么?

update - pub / sub info

应该包括pub / subs。非常简单我只是在一分钟内发布所有内容,虽然一旦它正常工作它会变得更聪明。我已删除了autopublish包。

发布

Meteor.publish("allGames", function(userId) {
    return Games.find();
});

订阅

Meteor.subscribe("allGames", this.userId);

正如您所看到的,我还没有使用userId

更新2 - 最小测试用例

我已将此简化为可重复的内容,看起来我对收藏品存在根本性的误解。我在这里整理了3个测试用例:

https://github.com/antiBaconMachine/meteorCollectionRenderingTests

我在3次测试中看到的输出是

  1. 没有游戏
  2. 计数,后跟等于流星服务器启动次数的记录
  3. 没有游戏
  4. 我希望第一个测试能够被动地呈现,因为forEach应该获取我假设被手把{{#each}}调用的文档。来自流星文档:

      

    游标是一个反应数据源。第一次在反应计算(例如,模板或自动运行)中使用fetch,map或forEach检索游标文档时,Meteor将注册对基础数据的依赖。

    第二次测试按照我的预期工作,这让我感到困惑,因为唯一的区别是我检索了计数。

    我假设最后一次测试失败,因为我在准备文件之前提取文件,一旦检索到,查询就不再被反应了?这只是猜测。

    如果对此有任何见解,我将感激不尽。

1 个答案:

答案 0 :(得分:2)

注意:初始答案和随后的错误再现完全不同。那人帮助发现了另一个。寻找这个答案的第二部分以获取真实信息。

回答最初的问题:

这种行为对我有意义:

让我们来看看你的问题:

Games.find({date: {$gte: new Date()}}, {sort: {date: 1}})

您正在寻找所有游戏,按日期大于 查询 创建的日期排序。

因此,假设您在数据库中有以下项目:

A, date: 100
B, date: 200
C, date: 300

您的客户端js已加载,当前时间为350。您的查询创建为Games.find({ date: {$gte: 350} }, {sort: {date: 1}});。当然A,B和C都在350日期之后,因此不会被渲染。

然后你将一个新游戏插入数据库,比如D, date: 400。是的,它应该显示在查看350之后创建的所有内容的查询中。

您期望什么行为?

对更新的补充:

这是一个错误。

此错误是针对鲨鱼渲染引擎提交的。新引擎(spark)已解决此问题,并将在下一个Meteor版本中发布。 (也许是0.7)

当您将minimongo游标作为模板数据上下文传递时,会发生错误。将数据传输到模板是非常不寻常的方式。我认为这就是为什么它存在了这么久但却没有被发现。

临时解决方法是不将游标作为数据上下文传递。相反,你可以传递id或name或其他任何东西,然后为callee模板提供一个单独的模板助手,返回一个合适的游标。

一个有趣的事情:不是将光标传递给模板,而是将其嵌入到#with块帮助器中,它将按预期工作:

{{#with games}}
      <ul>
        {{#if this.count}}
            {{#each this}}
            <li class="u-margin--sm">
                <a href="/game/show/{{_id}}" class="col-md-8">{{name}}</a>
            </li>
            {{/each}}
        {{else}}
        <span class="t-small">No games</span>
        {{/if}}
    </ul>
{{/with}}

一切正常:)。

Re:withFetch

如果您使用length而不是count,它会按预期工作。获取时,cursor返回一个普通的JS数组,它没有count属性,但有length