2013-05-01 23 views
6

为什么在下面的基本例子里面返回的collection里面呈现的函数是空的?
启用自动发布功能。页面加载调用命令
Coll.find().fetch() JavaScript控制台返回内部之后正确的设置项流星template.rendered - 为什么集合是空的?

这里是代码

t.js

Coll = new Meteor.Collection("coll"); 

if (Meteor.isClient) { 
    Template.tpl.rendered = function(){ 
    console.log(Coll.find().fetch()); // <-- This line prints empty array 
    }; 
} 

if (Meteor.isServer) { 
    Meteor.startup(function() { 
     if (Coll.find().count() === 0) { 
      var f = ["foo","bar"]; 
      for (var i = 0; i < f.length; i++) 
       Coll.insert({f: f[i]}); 
     } 
    }); 
} 

而且t.html文件

<head> 
    <title>test</title> 
</head> 

<body> 
    {{> tpl}} 
</body> 

<template name="tpl"> 
    Test tpl 
</template> 
+0

这是因为您的收藏尚未加载。 'Template.rendered'被触发,并不意味着你的集合被加载。检查[this](http://stackoverflow.com/questions/15129827/)线程。 – 2013-05-01 08:09:28

回答

5

流星建关闭数据线型结构回覆。这意味着当应用程序最初加载HTML时,首先发送JS,然后再发送数据。

您必须使用反应性来检查数据更改或检查集合的订阅何时完成(这需要删除自动发布软件包)。 (你可以看看如何将您的应用程序在文档移动到手动订阅:http://docs.meteor.com/#publishandsubscribe

订阅回调告诉你时,返回的数据:

Meteor.subscribe("coll", function() { 
    //Data subscription complete. All data is downloaded 
}); 

模板还可以做出反应(就像你正在做的那样),但是.rendered未被调用,因为流星首先检查模板的html是否已经改变& 只有当它不同时它会改变其HTML并调用呈现的回调。

你有什么作为一个选项这里是1)使用Deps.autorun代替,或

2)我不知道为什么你在你的呈现回调使用这一点,但如果有必要把它放在那里,你需要确保模板的HTML发生更改,方法是从集合中引入一些HTML,以便在引入新数据时进行更改。

+0

我也被困在这里。你能详细解释一下吗?我试图手动渲染一个模板,该模板生成一个c3 js图表,并试图从数据库加载数据,但获得上面的空数组。 – radtek 2014-10-21 03:00:27

+0

@radtek Meteor通过先发送html,然后再发送数据。当您呈现的回调触发时,数据可能不会或可能已发送。在绘制图表之前,您必须确保您使用上述方法之一或铁路路由器的'subscribe('..')。wait()'命令等待它到达。 – Akshat 2014-10-21 04:11:39

+0

是的,我知道的很多。我猜我以后是使用c3 js流星包的例子。对静态数据可以正常工作,但应该有一个使用db数据的最佳实践示例。我会看到我今晚晚些时候想到的。当我试图呈现html然后订阅并通过句柄放出数据时,我试图在模板本身内生成一个js脚本,但是当我为每个脚本创建一个时,句柄会创建一个新行,因此它甚至不是可解析的js。 var data = []; data.push({{each_item}}); 。所以我认为这太hacky,需要有更好的方法 – radtek 2014-10-21 14:39:37