删除后触发child_added [英] child_added gets triggered after remove
问题描述
我已经创建了此处理程序来监视正在创建的新子级.这个小技巧可以阻止child_added事件在每次页面加载时触发我的代码.相反,它仅在实际添加某些内容时触发.
I've created this handler to watch for new children being created. This little trick stops the child_added event from triggering my code on each page load. Instead it only gets triggered when something is actually added.
// Listen for new rooms being created
var first_room_added_after_load = true;
this._roomRef.endAt().limit(1).on('child_added', function(snapshot){
if (first_room_added_after_load) { // we want to skip the first room, because it will already exist
first_room_added_after_load = false;
return;
}
else {
this._onCreateRoom(snapshot);
}
}, this);
也就是说,当我在_roomRef中的节点上调用remove()时,将为已经存在的节点触发child_added.关于为什么以及如何阻止它的任何提示?
That said, when I call remove() on a node in _roomRef then child_added is triggered for a node that already exists. Any hints as to why, and how to stop it?
我还应该提及的是,这似乎只有在删除列表中已经存在的其他内容之后创建的内容时才会发生.如果我先删除较旧的项目,则不会触发child_added.
I should also mention this only seems to happen if I remove something that was created after something else already in the list. If I remove the older items first, then child_added is not triggered.
推荐答案
您似乎认为 endAt()
使用时间戳进行比较,因此它仅返回新的子代.但这根本不是它的工作原理.来自 endAt
的Firebase文档:
You seem to think the endAt()
uses a timestamp for comparison, so that it only returns new children. But that's simply not how it works. From the Firebase documentation for endAt
:
如果未提供任何参数,则终点将是数据的终点.
If no arguments are provided, the ending point will be the end of the data.
使用您的代码:
this._roomRef.endAt().limit(1)
您正在创建一个查询,该查询设置为始终返回一个孩子.条件是该子级是在创建查询后创建的.
You're creating a query that is set to always return a single child. The condition is that the child was created after you created the query.
查询就像在Firebase引用中子节点上的滑动窗口:它将始终包含(最多)一个子,这是在创建查询后创建的子.
A query is like a sliding window over the child nodes in your Firebase ref: it will always contain (at most) one child, a child that was created after you created your query.
假设您在创建查询时拥有以下子项:
Say you have these children when you create the query:
child1
child2
child3 <!-- last child present when creating the endAt() query -->
通过使用 endAt
查询将在 child3
之后植根".因此,它将不会触发 child1
, child2
和 child3
的任何事件.
By using endAt
query will be "rooted" after child3
. So it will not fire any events for child1
, child2
and child3
.
假设您添加了一个新孩子:
Say you add a new child:
child1
child2
child3 <!-- last child present when creating the endAt() query -->
child4
查询将为 child4
的 child_added
事件.
现在,如果我们添加另一个孩子:
Now if we add another child:
child1
child2
child3 <!-- last child present when creating the endAt() query -->
child4
child5
查询将为 child4
触发 child_removed
,为 child5
触发 child_added
.请注意, child4
实际上并未从Firebase中删除,它只是从查询结果中消失了(因为您要求将结果数限制为一个).
The query will fire a child_removed
for child4
and child_added
for child5
. Note that child4
was not actually removed from your Firebase, it just disappeared from the query results (since you asked to limit the number of results to just one).
当我们现在删除最新的孩子时,我们最终得到:
When we now remove the latest child, we end up with:
child1
child2
child3 <!-- last child present when creating the endAt() query -->
child4
查询将为 child5
触发 child_removed
,为 child4
触发 child_added
.这又来自于以下事实:您的查询被设置为始终包含(最多)在 child3
之后添加的一个节点.
And the query will fire a child_removed
for child5
and child_added
for child4
. This again comes from the fact that your query is set to always contain (at most) one node that was added after child3
.
似乎您只想为新添加的孩子获得一次 child_added
.在那种情况下,我不会在查询中使用 limit
,而是将创建会议室的时间戳记设置为其优先级:
It seems like you only want to get child_added
once for newly added children. In that case I would not use a limit
on the query, but instead I would set the timestamp that the room was created as its priority:
this._roomRef.push({
/* whatever properties you need for a room */,
'.priority': Firebase.ServerValue.TIMESTAMP
})
然后,您可以简单地以该优先级开始查询.
Then you can simply start the query at that priority.
this._roomRef.startAt(Date.now()).on('child_added', ...
这篇关于删除后触发child_added的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!