Элемент в добавленной таблице всегда дублируется при добавлении нового элемента в базу данных firebase - PullRequest
0 голосов
/ 13 января 2019

После добавления нового элемента в базу данных firebase все элементы добавленной таблицы 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 голосов
/ 13 января 2019

Вы слушаете событие 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').

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...