Meteor订阅onReady()和observe()添加了双重计数

时间:2013-12-14 10:14:52

标签: meteor

我想等待从订阅中下载所有数据,然后在开始时一次为它们创建地图标记。为此,我将会话变量设置为false。然后当onReady调用时,我初始化所有标记。然后我将会话变量设置为true,表示第一次传递已进入并初始化。在我的观察回调中,我检查会话变量,只要它是假的,我不添加任何标记。然后,如果它是真的,我将添加标记 - 假设这些标记的非已经初始化。然而,有时候,我会得到一个双重计数并创建两倍的标记。

我想问一个好的第一个问题是onReady和observe添加之间的关系是什么?它在文档中并不十分清楚。这甚至是正确的做事方式 - 在onReady完成之前创建一个会话变量来抑制观察添加的功能吗?我不这么认为。还要注意,双重计数并不是每次都发生,因此它是一个时间性的东西......有点烦人。

由于

1 个答案:

答案 0 :(得分:1)

是的,这是observe()的行为。当您最初运行observe时,它将具有一个初始查询,该查询将匹配所有内容并运行到added

onReady尚未触发但当时集合为空时它也存在,因此初始集合不可见。这在文档中提到

  

在观察返回之前,添加(或者已添加的)将被调用零次或多次以传递查询的初始结果。

我不确定如何避免最初的项目。我过去做过类似的事情:

var QueryHandle = Collection.find().observe({
    added: function() {
        if(!QueryHandle) return false;
    });

我知道这可以在服务器上运行,但我不确定它是否在客户端上运行。

另一种解决方案是在调用onReady之前运行句柄,并且只有在订阅完成时才停止返回:即

Meteor.subscribe("collection", function() {
   subscribed = true;
});

var QueryHandle = Collection.find().observe({
    added: function() {
        if(!subscribed) return false;
    } 
);

请注意不要在Deps.autorun中运行此操作,因为如果.find()查询参数被激活,它将再次运行。

有时可能会发生这种情况取决于服务器响应的速度。如果你使用Session它会变成一个反应式哈希,所以如果它发生得足够快,那么订阅返回true。请尝试使用普通变量。

如果它没有帮助,可能会有另一种方法来避免最初的方法和更深层次但可能需要深入了解livedata包。