将新元素添加到firebase-database时,附加表中的元素始终重复

时间:2019-01-12 22:53:27

标签: javascript firebase firebase-realtime-database

将新元素添加到firebase-database后,附加HTML表的所有元素都已复制。

我尝试使用下面的代码片段对其进行修复。但它不起作用。

var userlistings = document.querySelectorAll('userlisting')

    for(var i = 0; i < userlistings.length; i++){

    userlistings[i].remove();

    }

createElementWithText('userlisting');

这是完整的代码。

var dbRefUsers = firebase.database().ref().child('Web App').child('Users');

  dbRefUsers.on('value', gotData, errData); 

 function gotData(data){     

    var userlistings = document.querySelectorAll('userlisting')

    for(var i = 0; i < userlistings.length; i++){

    userlistings[i].remove();

    }

    var users = data.val();
    var keys = Object.keys(users)

    for (var i = 0; i < keys.length; i++){
        var k = keys[i];

        var userName = users[k].Name;
        var userEmail = users[k].Email;
        var userPassword = users[k].Password;

    console.log(userName, userEmail, userPassword);

   var appendingTo = document.getElementById("userlist");

   function createElementWithText(tag, text) {
    var elm = document.createElement(tag);
    elm.textContent = text;
    return elm;
    }

   var tr = document.createElement('tr');

   createElementWithText('userlisting');

   tr.appendChild(createElementWithText('td', userName));
   tr.appendChild(createElementWithText('td', userEmail));
   tr.appendChild(createElementWithText('td', userPassword));
   appendingTo.appendChild(tr);

    }
 }

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

您正在监听value上的/Web App/Users事件:

var dbRefUsers = firebase.database().ref().child('Web App').child('Users');
dbRefUsers.on('value', gotData, errData); 

当您连接此侦听器时,将立即调用gotData下的所有数据的快照来调用/Web App/Users。然后,只要那里的内容发生变化,就会使用最新数据的快照再次调用gotData。因此,此最新快照包含原始数据更改。

有两种主要的处理方法:

  1. 在重新呈现界面之前清除界面
  2. 收听子事件并执行详尽的更新

在重新呈现界面之前清除界面

最简单的方法是使userlist的每次调用都使gotData元素为空,

document.getElementById("userlist");
appendingTo.innerHTML = "";

这将起作用,但是最终您将重新渲染几乎相同的元素,这可能会导致不必要的闪烁。毫不奇怪,有一种方法可以通过...解决此问题。

收听子事件并执行详尽的更新

由于您监听了value事件,因此Firebase为您提供了该位置下所有数据的快照。您还可以侦听低一级的事件,在这种情况下,Firebase会告诉您何时添加了例如用户。

一个好的起点是听child_added

var appendingTo = document.getElementById("userlist");

dbRefUsers.on('child_added', gotNewChild, errData); 

function gotNewChild(userSnapshot){     
  var user = userSnapshot.val();

  var userName = user.Name;
  var userEmail = user.Email;
  var userPassword = user.Password;

  var tr = document.createElement('tr');

  tr.id = userSnapshot.key

  tr.appendChild(createElementWithText('td', userName));
  tr.appendChild(createElementWithText('td', userEmail));
  tr.appendChild(createElementWithText('td', userPassword));

  appendingTo.appendChild(tr);
}

这里需要注意的几件事:

  • gotNewChild内部没有循环,因为每个子节点/用户节点都会调用它。
  • 我设置了tr.id = snapshot.key,以便您以后可以使用tr通过用户的键来查询var userElm = document.getElemenyById(userSnapshot.key)
  • 此代码无效:

    var userlistings = document.querySelectorAll('userlisting')
    for(var i = 0; i < userlistings.length; i++){
       userlistings[i].remove();
    }
    

    我删除了(需要)代码,但是我强烈建议您学习自己解决这种类型的代码。我建议在for行上设置一个断点,并在调试器中运行代码。如果您检查userlistings,您将发现它不包含任何内容。这是因为您对createElementWithText('userlisting')不做任何事情。如果要删除tr元素,则需要使用document.querySelectorAll('#userlist > tr')进行选择。