Почему использование «один раз» вместо «на» ломает здесь что-то? - PullRequest
0 голосов
/ 04 августа 2020

Итак, я создал приложение, в котором вы вводите имя своей любимой книги и автора в форме, и оно генерирует карточку с этой информацией.

В форме есть флажок, чтобы отметить, владеете ли вы ею и кнопку «удалить».

Он работает с функцией addtoLibrary(), которая берет информацию из формы, помещает ее в объект, а этот объект - в firebase.

Внутри этой функции, У меня есть еще одна функция под названием render(), которая берет информацию из firebase и помещает ее в DOM.

Затем я добавил еще одну функцию с именем retrievefromDatabase(), которая также включает функцию render(), и просматривает список объектов для рисования карт для элементов, которые существуют в базе данных.

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что всякий раз, когда флажок установлен или снят, функция retrievefromDatabase() активируется и dr aws другая карта .

Думаю, если бы я мог изменить on во втором вызове базы данных на once здесь, это решило бы мою проблему. Но когда я это делаю, все поля в моей карточке отображаются как «undefined».

Я не уверен, почему он вообще это делает, потому что исходный вызов базы данных - это once, который перебирает каждый объект key, и при изменении флажка новые ключи объекта не появляются. Это просто изменение состояния объекта.

function retrievefromDatabase() {
  firebase.database().ref("Book").once("value", gotData);
      function gotData(Book) {
      var books = Book.val();
      var keys = Object.keys(books);
        for (var i = 0; i < keys.length; i++) {
          firebase.database().ref("Book/" + keys[i]).on("value", function(snapshot) {
          newPostKey = snapshot.key;    
          function oldBook(title, fname, lname, pubDate, contrib, own) {
            this.title = title;
            this.fname = fname;
            this.lname = lname;
            this.pubDate = pubDate;
            this.contrib = contrib;
            this.own = own;
          };          
          var archiveBook = new oldBook(snapshot.val().title, 
          snapshot.val().fname, 
          snapshot.val().lname, 
          snapshot.val().pubDate,
          snapshot.val().contrib,
          snapshot.val().own);
          render();
        })}}};

Ответы [ 2 ]

1 голос
/ 04 августа 2020

Когда вы добавляете слушателя в место в базе данных, вы получаете моментальный снимок со всеми данными в этом месте. Это означает, что нет необходимости прикреплять слушателя к узлам в этом месте в обратном вызове.

Кроме того, намного проще l oop над дочерними узлами снимка с помощью snapshot.forEach(), вместо извлечения ключей и последующего их использования.

Таким образом, ваш код можно упростить до:

function retrievefromDatabase() {
    firebase.database().ref("Book").once("value", (book) => {
        book.forEach((snapshot) => {
            newPostKey = snapshot.key;

            function oldBook(title, fname, lname, pubDate, contrib, own) {
                this.title = title;
                this.fname = fname;
                this.lname = lname;
                this.pubDate = pubDate;
                this.contrib = contrib;
                this.own = own;
            };
            var archiveBook = new oldBook(snapshot.val().title,
                snapshot.val().fname,
                snapshot.val().lname,
                snapshot.val().pubDate,
                snapshot.val().contrib,
                snapshot.val().own);
        })
        render();
    }
};

On on vs once:

  • если вы хотите получить данные только один раз, вы должны использовать once. Это также означает, что вам придется вызывать retrievefromDatabase каждый раз, когда вы хотите загрузить данные.
  • , если вы хотите продолжать отслеживать изменения в базе данных после извлечения данных, вы должны использовать on . В этом случае не забудьте вызвать retrievefromDatabase только один раз, так как вы не хотите подключать несколько постоянных слушателей.
0 голосов
/ 04 августа 2020

Это то, что я предпринял, и это сработало, но намного уродливее, чем решение Фрэнка:

function retrievefromDatabase() {
firebase.database().ref("Book").once("value", gotData);
  function gotData(Book) {
    var books = Book.val();
    var keys = Object.keys(books);
  
    for (var i = 0; i < keys.length; i++) {

      firebase.database().ref("Book/" + keys[i]).once("value", function(snapshot) {  
      titlesnap = snapshot.val().title; 
      fnamesnap = snapshot.val().fname;
      lnamesnap = snapshot.val().lname;
      pubsnap = snapshot.val().pubDate;
      contribsnap = snapshot.val().contrib;
      newPostKey = snapshot.key;

      const bookContainer = document.createElement("div");
      bookContainer.classList.add("book-container");
      const newVolume = document.createElement("div");
      newVolume.classList.add("volume");
      bookContainer.appendChild(newVolume);
      bookContainer.setAttribute('id', `${newPostKey}`);
      const frontCover = document.createElement("div");
      newVolume.appendChild(frontCover);
      frontCover.style.setProperty("background-color", getRandomColor());

      frontCover.innerHTML = "<br /><br />"
      + "<b>" + titlesnap + "</b>" + "<br /><br />" 
      + fnamesnap + "&nbsp;"
      + lnamesnap + "<br /><br />"
      + "Published: " + pubsnap + "<br />"
      + "Added by: <br />" + contribsnap + "<br />";

      const checkbox = document.createElement('input'); 
      checkbox.type = "checkbox"; 
      checkbox.id = "checkbox"; 
    
      if (snapshot.val().own == true) {
        checkbox.checked = true;
      }
      else {
        checkbox.checked = false;
      };  
      
    checkbox.addEventListener("change", function() {
    if (checkbox.checked === false) {
      firebase.database().ref('Book/' + bookContainer.id + '/own').set(false);
    }
    else if (checkbox.checked === true) {
      firebase.database().ref('Book/' + bookContainer.id + '/own').set(true);
        }});

    const label = document.createElement("label"); 
    label.appendChild(document.createTextNode(" I own a copy")); 
    const newgraf = document.createElement("p")
    
    frontCover.appendChild(checkbox);
    frontCover.appendChild(label);
    frontCover.appendChild(newgraf);
    
    const removeButton = document.createElement('button')
    frontCover.appendChild(removeButton);
    removeButton.textContent = 'Remove';
    removeButton.addEventListener("click", function(event){
        firebase.database().ref('Book/').child(bookContainer.id).remove()
        bookContainer.remove();
    })

      libraryContainer.insertAdjacentElement('afterbegin',bookContainer);
      });
};
  };};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...