我有一个像这样的模板助手
Template.index.allUpcomingGames = function() {
return Games.find({date: {$gte: new Date()}}, {sort: {date: 1}});
};
因此,如果我正确阅读文档,则只要此查询结果发生更改,就应重新呈现模板。
我看到的实际行为是,当我第一次加载页面(空的minimongo缓存)时,模板没有结果。当检测到增量更改并且强制重新呈现模板时,项目会神奇地出现,因此可能在查询返回之前发生初始页面加载,并且随后不会像我期望的那样被动地重新呈现。我究竟做错了什么?管理查询模板依赖关系的最佳实践是什么?
应该包括pub / subs。非常简单我只是在一分钟内发布所有内容,虽然一旦它正常工作它会变得更聪明。我已删除了autopublish包。
发布
Meteor.publish("allGames", function(userId) {
return Games.find();
});
订阅
Meteor.subscribe("allGames", this.userId);
正如您所看到的,我还没有使用userId
我已将此简化为可重复的内容,看起来我对收藏品存在根本性的误解。我在这里整理了3个测试用例:
https://github.com/antiBaconMachine/meteorCollectionRenderingTests
我在3次测试中看到的输出是
我希望第一个测试能够被动地呈现,因为forEach
应该获取我假设被手把{{#each}}
调用的文档。来自流星文档:
游标是一个反应数据源。第一次在反应计算(例如,模板或自动运行)中使用fetch,map或forEach检索游标文档时,Meteor将注册对基础数据的依赖。
第二次测试按照我的预期工作,这让我感到困惑,因为唯一的区别是我检索了计数。
我假设最后一次测试失败,因为我在准备文件之前提取文件,一旦检索到,查询就不再被反应了?这只是猜测。
如果对此有任何见解,我将感激不尽。
答案 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
。