为什么我的流星模板没有被动渲染

Why isn't my meteor template being reactively rendered?

本文关键字:被动 我的 流星 为什么      更新时间:2023-09-26

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

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

因此,如果我正确阅读了文档,则每当此查询结果更改时,都应重新呈现模板。

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

更新 - 发布/订阅信息

应该包括发布/订阅。 非常简单,我只是在此时发布所有内容,尽管一旦它起作用,它会变得更聪明。我已经删除了自动发布包。

发布

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

订阅

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

如您所见,我还没有使用userId

更新 2 - 最小测试用例

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

https://github.com/antiBaconMachine/meteorCollectionRenderingTests

我看到的 3 个测试的输出是

  1. 没有游戏
  2. 计数,后跟等于 meteor 服务器启动次数的记录
  3. 没有游戏

我希望第一个测试是被动呈现的,因为forEach应该获取我以为由车把调用的文档 {{#each}}.来自流星文档:

游标是反应式数据源。当您第一次在响应式计算(例如,模板或自动运行)中使用 fetch、map 或 forEach 检索游标的文档时,Meteor 将注册对底层数据的依赖关系。

第二个测试的工作方式与我预期的那样,这让我感到困惑,因为唯一的区别是我检索了计数。

我假设最后一个测试失败,因为我在文档准备就绪之前获取文档,一旦检索到查询就不再被动?这只是一个猜测。

对此的任何见解将不胜感激,我有点迷茫。

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

对初始问题的回答:

这种行为对我来说很有意义:

让我们看看您的查询:

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之后创建的所有内容的查询返回。

您期望什么行为?

更新的补充:

这是一个错误。

此错误是为鲨鱼渲染引擎提交的。新引擎(火花)已经解决了这个问题,并将在下一个流星版本中发布。(也许是0.7)

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

临时解决方法是不将游标作为数据上下文传递。相反,您可以传递 id 或名称或其他任何内容,然后为被调用方模板提供一个单独的模板帮助程序,该模板返回适当的游标。

一件有趣的事情:与其将光标传递给模板,不如将其嵌入到块助手 #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}}

一切都:)。

回复:与提取

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