Чтобы изучать объекты, я создал это библиотечное приложение, в котором вы вводите имя своей любимой книги и автора в форме, и он генерирует карточку с этой информацией.
В форме есть флажок, чтобы отметить, если вы владеете им и кнопкой «удалить».
Он работает с функцией addtoLibrary()
, которая берет информацию из формы, помещает ее в объект, а этот объект - в firebase.
Внутри Эта функция, у меня есть другая функция, называемая render()
, которая берет информацию из firebase и помещает ее в DOM.
Затем у меня было приложение, которое рисовало DOM каждый раз, когда приложение открывается, чтобы оно отображало все предыдущие записи.
Итак, я создал другую функцию с именем retrievefromDatabase()
, которая также включает функцию render()
и просматривает список объектов, чтобы перерисовать их.
Проблема в том, что я Однако теперь, когда этот флажок установлен или снят, функция retrievefromDatabase()
активируется и dr aws другая карта.
Я столкнулся с этой проблемой с моей кнопка «удалить», которая также изменила состояние firebase и нарисовала новую карту. Чтобы исправить это, я изменил один вызов firebase с .on
на .once
, и это помогло.
Но кнопку «удалить» легко, потому что вы не можете постоянно менять ее состояние взад и вперед.
Я мог бы запустить свой retrievefromDatabase()
только один раз, но тогда, если бы другой пользователь добавил карту, он не будет динамически обновляться. Но он покажет, когда он будет перезагружен, и я могу с этим жить.
Было бы лучше, если бы retrievefromDatabase()
работал как addtoLibrary()
, который я могу установить флажок к моему удовольствию, потому что он не читает из firebase, только записывая в нее изменения.
Соответственно, новые карты тянутся только в том случае, если они изначально были в базе данных. Любая новая отправленная карта не имеет этой проблемы.
Итак, я думаю, что моя проблема в том, что я плохо управляю базой данных. Я потратил неделю, пытаясь понять, как использовать CRUD, поэтому очевидно, что я не профессионал!
Можете ли вы предложить решение?
let newPostKey;
let titlesnap;
let fnamesnap;
let lnamesnap;
let pubsnap;
let contribsnap;
function Book(title, fname, lname, pubDate, contrib, own) {
this.title = title;
this.fname = fname;
this.lname = lname;
this.pubDate = pubDate;
this.contrib = contrib;
this.own = own;
};
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 addBook = new oldBook(snapshot.val().title,
snapshot.val().fname,
snapshot.val().lname,
snapshot.val().pubDate,
snapshot.val().contrib,
snapshot.val().own);
render(oldBook);
})}}};
retrievefromDatabase();
const submitButton = document.querySelector(".submitButton")
submitButton.addEventListener("click", e => {
// the prevents the field from clearing on submit
e.preventDefault();
addBookToLibrary();
})
function addBookToLibrary() {
let title = document.querySelector("#title").value;
let fname = document.querySelector("#fname").value;
let lname = document.querySelector("#lname").value;
let pubDate = document.querySelector("#pubDate").value;
let contrib = document.querySelector("#contrib").value;
let own = document.querySelector("#own").checked;
var addBook = new Book(title, fname, lname, pubDate, contrib, own);
// I could just put document.querySelector values into var addBook but this is clearer
newPostKey = firebase.database().ref().child('Book').push().key;
firebase.database().ref().child('Book').child(newPostKey).set(addBook);
// console.log(newPostKey);
// myLibrary.push(addBook);
render();
document.querySelector("#title").value = "";
document.querySelector("#fname").value = "";
document.querySelector("#lname").value = "";
document.querySelector("#pubDate").value = "";
document.querySelector("#contrib").value = "";
document.querySelector("#own").checked = false;
// I can also shorten this with form.reset()
// https://discord.com/channels/505093832157691914/690590001486102589/736653879684628491
};
function render() {
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());
let TitleRef = firebase.database().ref('Book/' + newPostKey + '/title');
TitleRef.on('value', function(snapshot) {
titlesnap = snapshot.val();
});
// why is this reversed? variable precedes
let FnameRef = firebase.database().ref('Book/' + newPostKey + '/fname');
FnameRef.on('value', function(snapshot) {
fnamesnap = snapshot.val();
});
let LnameRef = firebase.database().ref('Book/' + newPostKey + '/lname');
LnameRef.on('value', function(snapshot) {
lnamesnap = snapshot.val();
});
let pubRef = firebase.database().ref('Book/' + newPostKey + '/pubDate');
pubRef.on('value', function(snapshot) {
pubsnap = snapshot.val();
});
let contribRef = firebase.database().ref('Book/' + newPostKey + '/contrib');
contribRef.on('value', function(snapshot) {
contribsnap = snapshot.val();
});
frontCover.innerHTML = "<br /><br />"
+ "<b>" + titlesnap + "</b>" + "<br /><br />"
+ fnamesnap + " "
+ lnamesnap + "<br /><br />"
+ "Published: " + pubsnap + "<br />"
+ "Added by: <br />" + contribsnap + "<br />";
// reads checkbox form, adds it to the rendered volume and interprets value given
const checkbox = document.createElement('input');
checkbox.type = "checkbox";
checkbox.id = "checkbox";
if (document.getElementById("own").checked == true) {
checkbox.checked = true;
}
else if (document.getElementById("own").checked == true) {
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);
};
function getRandomColor() {
color = "hsl(" + Math.random() * 360 + ", 100%, 20%)";
return color;
}
Если вы хотите увидеть это в действии: https://project-library.acchang.repl.co/