javascript - 检索firebase对象以绘制带有复选框的卡片,但每次复选框更改时都会绘制一张新卡片
问题描述
为了学习对象,我构建了这个图书馆应用程序,您可以在表格中输入您最喜欢的书名和作者的名字,它会生成一张包含该信息的卡片。
表单上有一个复选框来标记您是否拥有它和一个“删除”按钮。
它与一个addtoLibrary()
函数一起工作,该函数从表单中获取信息,将其放入一个对象中,然后将该对象放入 firebase。
在该函数中,我有另一个函数调用render()
,它从 firebase 获取信息并将其放入 DOM。
接下来,我让应用程序在每次打开应用程序时都在 DOM 上绘图,以便它显示所有以前的条目。
因此,我构建了另一个名为的函数,该函数retrievefromDatabase()
也包含该render()
函数,并循环遍历对象列表以重绘它们。
不过,我现在面临的问题是,无论何时选中或取消选中复选框,该retrievefromDatabase()
功能都会激活并抽出另一张牌。
我的“删除”按钮遇到了这个问题,它也改变了firebase的状态并绘制了一张新卡。为了解决这个问题,我将 firebase 上的一个调用从.on
to更改为.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/
解决方案
明白了,我不得不重写retrievefromDatabase()
没有render()
:
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 + " "
+ 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);
});
};
};};
推荐阅读
- python - 如何使用 pyside2 在 Qtableview 中显示(和格式化)日期时间数据
- javascript - 如何从请求中返回此函数中的 var?
- azure-devops - 如何从 Power bi 中的 Azure DevOps 查询工作项的状态更改
- angular - CORS 策略已阻止对 XMLHttpRequest 的访问。请求的资源上不存在“Access-Control-Allow-Origin”标头
- apache-nifi - 如何配置 PutFile 使其按 24 小时计划运行,但运行时间与传入流文件的数量一样多
- svelte - 使用附加的 svelte 组件并在相同的 Javascript 上下文中创建窗口
- sql - 使用 LIKE 运算符或更好的方法连接 2 个表的最佳实践
- python - Flask 自定义装饰器
- ios - 在获取数据 Firebase / Swift 之前加载的 TableView
- r - R Markdown:在“参考”部分之后放置一个附录?