javascript - 为什么我的 meteor 模板没有被 react 性渲染?

标签 javascript meteor

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

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 应该获取我假设由 handlebars {{#each}} 调用的文档。从 meteor 文档:

Cursors are a reactive data source. The first time you retrieve a cursor's documents with fetch, map, or forEach inside a reactive computation (eg, a template or autorun), Meteor will register a dependency on the underlying data.

第二个测试如我所料,这让我感到困惑,因为唯一的区别是我检索了计数。

我假设最后一个测试失败了,因为我在文档准备好之前获取文档并且一旦检索到查询就不再是响应式(Reactive)的?这只是一个猜测。

对此有任何见解,我将不胜感激。

最佳答案

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

第一个问题的答案:

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

让我们看看您的查询:

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

您期望什么行为?

更新补充:

这是一个错误。

此错误是为 shark 渲染引擎提交的。新引擎 (spark) 解决了这个问题,将在下一个 Meteor 版本中发布。 (可能是 0.7)

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

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

一件有趣的事:你可以将光标嵌入到#with block helper 中,而不是将光标传递给模板,它会按预期工作:

{{#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}}

一切正常:)。

回复:withFetch

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

关于javascript - 为什么我的 meteor 模板没有被 react 性渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19759332/

相关文章:

Accounts.onCreateUser 中的 Meteor Promise

javascript - 队列.js : difference between array of functions & array of closures?

email - 在 Meteor 中验证电子邮件的正确方法

javascript - 如何在 Meteor 中验证服务器上的用户创建

javascript - Node JS 访问音频接口(interface)

javascript - 将函数值从父级传递给子级

JAVASCRIPT:如何浏览对象

javascript - 使用 HTML5 播放双音频 MKV/AVI 视频

javascript - 错误 : Support for the experimental syntax 'optionalChaining' isn't currently enabled, 但它是

javascript - 如何在 bootbox 中加载附加了 javascript 方法的自定义元素?