[英]how should i dynamically update a firebase document
我正在使用 JS 和 Firebase 为我的投资组合开发一个简单的笔记应用程序。在我告诉你发生了什么之前,我觉得我需要向你展示我的代码是如何工作的,如果你有任何提示和疑虑,请告诉我它将不胜感激。 话虽如此,让我们“一起”看看。 我正在使用这个 class 来创建笔记:
const htmlElements = [document.querySelector('.notes'), document.querySelector('.note')];
const [notesDiv, noteDiv] = htmlElements;
class CreateNote {
constructor(title, body) {
this.title = title;
this.body = body;
this.render = () => {
const div1 = document.createElement('div');
div1.className = 'notes-prev-container';
div1.addEventListener('click', () => { this.clickHandler(this) });
const div2 = document.createElement('div');
div2.className = 'notes-prev';
const hr = document.createElement('hr');
hr.className = 'notes__line';
// Nest 'div2' inside 'div1'
div1.appendChild(div2);
div1.appendChild(hr);
/*
Create Paragraph 1 & 2 and give them the same
class name and some text
*/
const p1 = document.createElement('p');
p1.className = 'notes-prev__title';
p1.innerText = this.title;
const p2 = document.createElement('p');
p2.className = 'notes-prev__body';
p2.innerText = this.body;
// Nest p 1 & 2 inside 'div2'
div2.appendChild(p1);
div2.appendChild(p2);
// Finally, render the div to its root tag
notesDiv.appendChild(div1);
}
}
/*
Every time this method is called, it creates 2 textareas,
one for the note title and the other for its body then it
appends it to the DOM.
*/
renderNoteContent () {
const title = document.createElement('textarea');
title.placeholder = 'Title';
title.value = this.title;
title.className = 'note__title';
const body = document.createElement('textarea');
body.placeholder = 'Body';
body.value = this.body;
body.className = 'note__body';
noteDiv.appendChild(title);
noteDiv.appendChild(body);
}
/*
When this method is called, it checks to see if there's a
note rendered already (childElementCount === 1 because there's a
button, so if there's only this button it means there's no
textareas rendered).
If yes, then merely call the renderNoteContent method. Else
get the tags with the classes 'note__title' and 'note__body'
and remove them from the DOM, then call renderNoteContent to
create the textareas with the clicked notes values.
This function gets mentioned at line 19.
*/
clickHandler(thisClass) {
if (noteDiv.childElementCount === 1) {
thisClass.renderNoteContent();
} else {
document.querySelector('.note__title').remove();
document.querySelector('.note__body').remove();
thisClass.renderNoteContent();
}
}
}
现在我需要 2 个按钮,分别是createNotesButton
和saveNotesButton
。 这 2 个按钮必须位于 function 内,将在.onAuthStateChanged
内调用(为什么?因为它们需要访问 firebase 身份验证上的currentUser
)。
我希望createNotesButton
创建一个笔记原型,将其渲染到 DOM 并在 firestore 上创建一个新文档,该文档内容将存储在该文档中。 我是这样做的:
PS:我觉得我没有正确使用这个 class,所以如果你有任何提示,我再次感谢。
import {db} from '../../firebase_variables/firebase-variables.js';
import {CreateNote} from '../create_notes_class/create_notes_class.js';
const htmlElements = [
document.querySelector('.createNotes-button'),
document.querySelector('.saveNotes-button')
];
const [createNotesButton, saveNotesButton] = htmlElements;
function clickHandler(user) {
/*
1. Creates a class.
2. Creates a new document on firebase with the class's empty value.
3. Renders the empty class to the DOM.
*/
createNotesButton.addEventListener('click', () => {
const note = new CreateNote('', '');
note.render();
// Each user has it's own note collection, said collection has their `uid` as name.
db.collection(`${user.uid}`).doc().set({
title: `${note.title}`,
body: `${note.body}`
})
})
}
现在我需要一个saveNotesButton
,他是我遇到问题的那个。 他需要将显示的笔记内容保存在 firestore 上。 这是我尝试做的事情:
import {db} from '../../firebase_variables/firebase-variables.js';
import {CreateNote} from '../create_notes_class/create_notes_class.js';
const htmlElements = [
document.querySelector('.createNotes-button'),
document.querySelector('.saveNotes-button')
];
const [createNotesButton, saveNotesButton] = htmlElements;
function clickHandler(user) {
createNotesButton.addEventListener('click', () => {...})
/*
1. Creates 2 variables, `title` and `body, if there's not a note being displayed
their values will be null, which is why the rest of the code is inside an if
statement
2. If statement to check if there's a note being displayed, if yes then:
1. Call the user's note collection. Any document who has the title field equal to the
displayed note's value gets returned as a promise.
2. Then call an specific user document and update the fields `title` and `body` with
the displayed note's values.
3. If no then do nothing.
*/
saveNotesButton.addEventListener('click', () => {
const title = document.querySelector('.note__title');
const body = document.querySelector('.note__body');
db.collection(`${user.uid}`).where('title', '==', `${title.value}`)
.get()
.then(userCollection => {
db.collection(`${user.uid}`).doc(`${userCollection.docs[0].id}`).update({
title: `${title.value}`,
body: `${body.value}`
})
})
.catch(error => {
console.log('Error getting documents: ', error);
});
});
}
这没有用,因为我使用title.value
作为查询,所以如果我更改它的值,它也会将查询方向更改为不存在的路径。
所以这里的问题是:我怎样才能让 saveNotesButton 完成它的工作? 我正在考虑为每个笔记添加另一个字段,不会改变的东西,所以我可以轻松识别和编辑每个笔记。 同样,如果我的代码中有您认为可以或应该格式化的内容,请告诉我,我正在使用这个项目来巩固我的原生 JS 知识,所以请耐心等待。 我觉得如果我使用 React,我会在某个时候完成这个,但绝对不会学到那么多,无论如何提前感谢您的帮助。
我正在考虑为每个笔记添加另一个字段,不会改变的东西,所以我可以轻松识别和编辑每个笔记。
是的,您绝对需要为 firestore 中的每个笔记文档提供一个不可变的标识符,以便您可以明确地引用它。 每当您在具有任何数据库的任何应用程序中存储数据 object 时,您几乎总是需要这个。
但是,firestore 已经为你做了这件事:在调用db.collection(user.uid).doc()
之后你应该得到一个带有 ID的文档。 这是您在更新笔记时要使用的 ID。
与 DOM 交互的代码部分需要跟踪这一点。 我建议将创建 firestore 文档的代码移动到CreateNote
的构造函数中并将其存储在this
上。 您还需要那里的用户 ID。
constructor(title, body, userId) {
this.title = title;
this.body = body;
const docRef = db.collection(userId).doc();
this.docId = docRef.id;
/* etc. */
然后,只要您拥有CreateNote
的实例,您就会知道要引用的正确用户和文档。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.