如何有效地使用child_added

时间:2017-07-08 02:07:57

标签: javascript firebase firebase-realtime-database

我非常熟悉“child_added”,“child_changed”,“child_removed”和“value”的概念。 每当我使用一个应该动态更新自己的列表时,我应该使用除“value”之外的所有函数,每当我只需要一个静态的数据快照时,我就会使用“value”。

我的问题如下:

每当我有一个列表时,它是否真的是编写三个触发器的最佳方式(如果算上“child_moved”,则为四个)?一个简单的应用程序有很多列表。 如果是的话,如何在javascript中以最有效的方式完成?我目前的做法如下:

  • on child_added:迭代我的整个列表;看看密钥等于我刚从事件中获得的密钥,并将其值保存为oldValue;现在找到prevChildKey的索引,并在从列表中删除myList [myList.indexOf(oldValue)]的同时在prevChildKey的索引后插入刚收到的子项
  • on child_changed:迭代我的整个列表;看看密钥等于我刚从事件中获得的密钥,并将其值保存为oldValue; set myList [myList.indexOf(oldValue)] = newValue;
  • on child_removed:与上面相同,只是使用myList.splice(...)
  • on child_moved:我没有实现这个。但是当我调用child_changed时,我可能会需要它,这会导致我的元素的排序发生变化。所以与child_added
  • 有一个非常相似的逻辑

有没有办法以更优雅的方式处理这个问题?我首先尝试通过myList [child.key]访问该元素,但这对我不起作用。

编辑:添加了代码来演示,我的应用程序中的每个列表都有很多代码

myRef.orderByChild("timestamp").on("child_added",(message,prevChildKey) => {
        //Transform the firebase-date into my own format
        var template = {
          senderName: message.val().sender,
          time:  message.val().timestamp,
          id: message.key}

        //Check where to add this
        if(prevChildKey){
            this.messages.forEach(currentMessage => {
                if(currentMessage.id === prevChildKey){
                    var indexToAdd = this.messages.indexOf(currentMessage);
                    this.messages.splice(indexToAdd+1,0,template];
                }
            });
        }else
            this.messages.unshift(template);

});
myRef.on("child_changed", message => { //orderByChild makes no sense here, right ?
    //Transform the firebase-date into my own format
    var template = {
        senderName: message.val().sender,
        time:  message.val().timestamp,
        id: message.key}

    var toBeUpdated = undefined;
    this.messages.forEach(currentMessage => {
        if(currentMessage.id === message.id){
            this.messages[this.messages.indexOf(currentMessage)] = template;
        }
    })

    //How do I preserve ordering here, since I was ordering by timestamp on child_added before and I don't check if that value changed
}
myRef.on("child_removed", oldMessage => {

    //Remove the message
    this.messages.forEach(currentMessage => {
        if(currentMessage.id === oldMessage.id){
            this.messages.splice(this.messages.indexOf(currentMessage),1);
        }
    })
}
myRef.orderByChild("timestamp").on("child_moved", (message,prevChildKey) => { //Not too sure, how this works. Do I need the orderByChild here to preserve it ?

    var messageToMove = undefined;
    var messagePosition = undefined;
    var indexToMoveTo = undefined;
    this.messages.forEach(currentMessage => {
        if(currentMessage.id === message.id){
            messagePosition = this.messages.indexOf(currentMessage);
            messageToMove = this.messages[messagePosition];
        }
        if(currentMessage.id === prevChildKey){
            indexToMoveTo = this.messages.indexOf(currentMessage) + 1;
        }
    })

    //Remove the message from where it was
    this.messaged.splice(messagePosition,1);
    //Add the message at the new position
    this.messages.splice(indexToMoveTo,0,messageToMove);

}

1 个答案:

答案 0 :(得分:0)

  

所以我需要将我从firebase获得的元素映射到我的本地   代表它。

哦!这很简单!

如您所知,Firebase将其数据存储在键:值对中。

因此,例如用户节点将是

InstallShield

如果要更改节点中的名称,比如Bill to Billy,则uid_0节点(和子数据)将在快照中传递给您的应用程序,密钥为uid_0。该密钥对应于您存储在阵列中的数据。

有很多方法可以解决这个问题。

一种方法是将数组中的对象存储为键值对的字典。一些伪代码..

users
   uid_0
      name: "Bill" 
   uid_1
      name: "Larry"

但是,一种“更为分级”的方法是创建一个用户类并将其存储在数组中,并将键(uid_0)作为类的属性之一

myDictionary = [ "uid_0": [name: "Billy"] ]
myArray[0] = myDictionary

然后,当您的应用收到快照时,您可以在数组中查询从snapshot.key

收到的userClass.key。

总体而言,一切都是通过密钥存储和访问Firebase,它保持一致且不变,因此它是用于使您的朋友(消息)阵列与Firebase同步的工具。

编辑:如果您希望通过将键和元素编号存储在HashMap(字典)中来直接访问已排序的数组对象,则可以实现链接列表。

UserClass {
   key = ""
   name = ""
}

let aUser = UserClass
aUser.key = snapshot.key
aUser.name = snapshot.value("name") //loose pseudo code, dont copy/paste!

myArray[0] = userClass

然后打印出uid_0的索引

Map<String, String> map = new HashMap<String, String>();
map.put("uid_0", "0");

输出索引:0

如果您只想使用一种存储机制,可以使用TreeMap(自然顺序)或LinkedHashMap。

System.out.println(map.get("uid_0"));