繁体   English   中英

Meteor findOne查询在一个模板助手中返回undefined。 在其他模板助手中,相同的查询效果很好

[英]Meteor findOne query returns undefined in one template helper. In other template helpers, same query works well

假设我有一个名为GameStatus的Meteor集合。 我有不同角色的用户,但我为所有用户发布了GameStatus集合。 我只是在server / publications.coffee中使用以下内容

Meteor.publish 'gamestatus', ->
    GameStatus.find()

对于两个角色('S'和'B'),当我使用以下模板助手(在文件client / views / seller.coffeeclient / views / buyer.coffee中定义)时,我没有问题。

currentRound: ->
    return GameStatus.findOne().currentRound

对于这些我永远不会得到以下错误。

Uncaught TypeError: Cannot read property 'currentRound' of undefined 

但是对于另一个角色('admin'),使用相同的模板助手(在文件client / views / admin.coffee中定义)给出了上面显示的Uncaught TypeError。 如果我改为写,它可以工作:

currentRound: ->
    return GameStatus.findOne()?.currentRound

我有点理解为什么会这样。 我认为,在加载页面时,该集合首先不可用,然后就可以使用了。 但为什么上面显示的其他模板不会发生这种情况?

如果有人可以帮助澄清这一点,我们将非常感激。

我确信收集准备好的时候并不总是一致的,所以如果你想要涵盖所有基础,请始终为未准备好收集的情况编写代码。

处理未准备好的集合有一种快速而肮脏的方法,以及您可以在todos示例中找到的更复杂的解决方案。

快速而肮脏的解决方案看起来像这样。

currentRound: ->
  gameStatusrecord = GameStatus.findOne();
  if(gameStatusRecord) 
    gameStatusRecord.currentRound

这会奏效。 在集合准备好之前,currentRound将返回null,并且您的模板将短暂呈现,并且可能只显示当前轮次的空白。 所以不是理想的用户体验,但不是很大的交易。

对于更复杂的解决方案,您可以使用“就绪”功能检查您订阅的集合是否已准备好进行查询。 如果集合尚未就绪,您可以渲染其他模板,例如“loading”,这样可以保证在集合准备好之前不会调用currentRound助手。

例如,在todos示例中,客户端订阅了todos.js第24行的“lists”集合:

var listsHandle = Meteor.subscribe('lists', function () {

然后在todos.js的第80行上为列表模板定义一个辅助函数

Template.lists.loading = function () {
  return !listsHandle.ready();
};

然后在todos.html第20行的列表模板中,除非listsHandle准备就绪,否则它不会尝试呈现任何模板。

<h3>Todo Lists</h3>
{{#if loading}}
  <div id="lists">Loading...</div>
{{else}}
  <div id="lists">
    {{#each lists}}
    <!--etc.-->

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM