将新元素添加到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);
}
}
有人可以帮我解决这个问题吗?
答案 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
。因此,此最新快照包含原始数据和更改。
有两种主要的处理方法:
最简单的方法是使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')
进行选择。