我想等待从订阅中下载所有数据,然后一开始就为它们创建映射标记。为此,我将会话变量设置为false。然后,当onReady调用时,我初始化所有标记。然后,我将会话变量设置为true,表示第一次交付已进入并初始化。在我的观察回调中,我检查会话变量,只要它为false,我就不添加任何标记。然后,如果它是真的,我将添加标记——假设这些标记中没有一个已经初始化。然而,有时,我会得到双倍的计数,并创建两倍多的标记。
我想首先要问的一个好问题是onReady和observe-added之间的关系是什么?这在文件中不是很清楚。这甚至是正确的做法吗?创建一个会话变量来抑制observe-added函数,直到onReady完成?我不这么认为。还要注意,重复计数并不是每次都会发生,所以这是一个时间问题。。。有点烦人。
感谢
是的,这就是observe()
的行为。当您最初运行observe时,它将有一个匹配所有内容的初始查询,并运行到added
中。
当onReady
尚未激发,但此时集合为空,因此初始集合不可见时,它也会出现。文档中提到了这一点
在观察返回之前,added(或addedAt)将被调用零次或多次,以传递查询的初始结果。
我不完全确定如何避免最初的项目。我过去做过这样的事情:
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
,它将成为一个反应散列,因此如果它发生得足够快,则subscribed将返回true。请尝试使用普通变量。
如果它没有帮助,可能有一种替代方法可以避免最初的方法和更深层次的方法,但它可能需要深入研究livedata
包。