Meteor findOne查询在一个模板助手中返回undefined。在其他模板助手中,相同的查询效果很好 [英] Meteor findOne query returns undefined in one template helper. In other template helpers, same query works well

查看:83
本文介绍了Meteor findOne查询在一个模板助手中返回undefined。在其他模板助手中,相同的查询效果很好的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

  currentRound: - > 
返回GameStatus.findOne()。currentRound

对于这些我从未收到以下错误。

 未捕获TypeError:无法读取未定义


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

  currentRound: - > 
返回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行的列表模板定义一个辅助函数。

 模板。 lists.loading = function(){
return!listsHandle.ready();
};

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

 < h3> Todo Lists< / h3> 
{{#if loading}}
< div id =lists>正在加载...< / div>
{{else}}
< div id =lists>
{{#each lists}}
<! - etc .-->


Suppose I have a Meteor collection called GameStatus. I have users with different roles, but I publish the GameStatus collection for all users. I simply use the following in server/publications.coffee

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

For two of the roles ('S' and 'B') I have no problem when I use the following Template helper (defined in files client/views/seller.coffee and client/views/buyer.coffee)

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

For these I never get the following error.

Uncaught TypeError: Cannot read property 'currentRound' of undefined 

But for another role ('admin'), using the same template helper (defined in file client/views/admin.coffee) gives the above show Uncaught TypeError. It works if I instead write:

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

I sort of understand why this works. I think, the collection is first not available when the page is being loaded, then it becomes available. But why does this not happen for other templates shown above?

Would really appreciate if someone can help clarify this.

解决方案

I believe exactly when a collection is ready won't always be consistent, so if you want to cover all your bases, always code for the case where a collection is not ready.

There's a quick-and-dirty way of dealing with collections that aren't ready, and a more sophisticated solution you can find in the todos example.

Quick and dirty solution would look like this.

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

This will work. Until the collection is ready, currentRound will return null, and your template will briefly render and probably just show a blank for current round. So not ideal user experience but not a huge deal.

For a more sophisticated solution, you can check whether a collection that you have subscribed is ready to be queried using the "ready" function. If a collection is not ready, you can render some other template, such as "loading", which guarantees that the currentRound helper won't ever be called until the collection is ready.

For instance, in the todos example, the client subscribes to the "lists" collection on line 24 of todos.js:

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

Then defines a helper function for the lists template on line 80 of todos.js

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

Then in the lists template in todos.html line 20, it doesn't try to render any templates unless the listsHandle is ready.

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

这篇关于Meteor findOne查询在一个模板助手中返回undefined。在其他模板助手中,相同的查询效果很好的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆