Javascript Firebase在添加/删除数据时,应用程序会执行多次功能
我的理财应用程序有问题。当我从我的应用程序(产品集合)中添加/删除数据时,我的应用程序会执行多个函数“sumPrices()”。例如:当我添加一个产品时,生成一次,添加另一个产品,生成两次,添加另一个产品生成三次等。这与删除数据的方式相同 A我的代码中有什么错误吗 Callback.push数据do数组,其中我从firebase取消订阅事件。 AddStatsUI将UI添加到我的DOM index.js:Javascript Firebase在添加/删除数据时,应用程序会执行多次功能,javascript,firebase,google-cloud-firestore,Javascript,Firebase,Google Cloud Firestore,我的理财应用程序有问题。当我从我的应用程序(产品集合)中添加/删除数据时,我的应用程序会执行多个函数“sumPrices()”。例如:当我添加一个产品时,生成一次,添加另一个产品,生成两次,添加另一个产品生成三次等。这与删除数据的方式相同 A我的代码中有什么错误吗 Callback.push数据do数组,其中我从firebase取消订阅事件。 AddStatsUI将UI添加到我的DOM index.js: // delete products const handleTableClick
// delete products
const handleTableClick = e => {
console.log(e); // mouseevent
if (e.target.tagName === 'BUTTON'){
const id = e.target.parentElement.parentElement.getAttribute('data-id');
db.collection('users')
.doc(user.uid)
.collection('products')
.doc(id)
.delete()
.then(() => {
// show message
updateMssg.innerText = `Product was deleted`;
updateMssg.classList.add('act');
setTimeout(() => {
updateMssg.innerText = '';
updateMssg.classList.remove('act');
}, 3000);
productUI.delete(id);
products.sumPrices(user.uid, callbacks).then(value => {
sumStats.addStatsUI('','');
const unsubscribe = db.collection('users').doc(user.uid).get().then(snapshot => {
sumStats.addStatsUI(value[0], snapshot.data().budget);
})
callbacks.push(unsubscribe);
});
})
}
}
table.addEventListener('click', handleTableClick);
callbacks.push(() => table.removeEventListener('click', handleTableClick))
//add new products to firebase
const handleExpenseFormSubmit = e => {
e.preventDefault();
const name = expenseForm.productName.value.trim();
const price = Number(expenseForm.price.value.trim());
console.log(`Product added: ${name}, ${price}`);
const user = firebase.auth().currentUser.uid;
products.addProduct(name, price, user)
.then(() => {
products.sumPrices(user, callbacks).then(value => {
sumStats.addStatsUI('','');
const unsubscribe = db.collection('users').doc(user).onSnapshot(snapshot => {
sumStats.addStatsUI(value, snapshot.data().budget);
})
callbacks.push(unsubscribe);
});
expenseForm.reset()
})
.catch(err => console.log(err));
}
expenseForm.addEventListener('submit', handleExpenseFormSubmit);
callbacks.push(() => expenseForm.removeEventListener('submit', handleExpenseFormSubmit))
//get the products and render
const unsubscribe = products.getProducts((data, id) => {
console.log(data, id);
productUI.render(data, id);
}, user.uid);
callbacks.push(unsubscribe);
//update budget + form
const handleBudgetFormSubmit = e => {
e.preventDefault();
//update budget
const budget = Number(budgetForm.budget_value.value.trim());
sumStats.addStatsUI('', '');
products.updateBudget(budget, user.uid);
//reset form
budgetForm.reset();
const budgetCart = document.querySelector('#budget');
budgetCart.classList.remove('active');
// show message
updateMssg.innerText = `Your budget was updated to ${budget}$`;
updateMssg.classList.add('act');
setTimeout(() => {
updateMssg.innerText = '';
updateMssg.classList.remove('act');
}, 3000);
};
budgetForm.addEventListener('submit', handleBudgetFormSubmit);
callbacks.push(() =>
budgetForm.removeEventListener('submit', handleBudgetFormSubmit)
);
product.js:
class Product {
constructor(name, price, budget, user) {
this.products = db.collection('users');
this.budget = budget;
this.name = name;
this.price = price;
this.user = user;
}
async addProduct(name, price, user) { //dodaje produkt do firebase
const now = new Date();
const product = {
name: name,
price: price,
created_at: firebase.firestore.Timestamp.fromDate(now),
};
const response = await this.products.doc(user).collection('products').add(product);
return response;
}
getProducts(callback, user){ //download list from firebase
this.products.doc(user).collection('products')
.orderBy("created_at", "desc")
.onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
if(change.type === 'added'){
//udpate UI
return callback(change.doc.data(), change.doc.id);
}
});
});
}
updateBudget(budget, user){
this.budget = budget;
db.collection('users').doc(user).update({budget: budget});
// callbacks.push(unsubscribe);
}
async sumPrices(user, callbacks){
let finish = [];
const unsubscribe = this.products.doc(user).collection('products').onSnapshot(snapshot => {
let totalCount = 0;
snapshot.forEach(doc => {
totalCount += doc.data().price;
});
const a = totalCount;
console.log(a);
finish.push(a);
return finish;
})
callbacks.push(unsubscribe);
return finish;
};
})
sumStatsUI.js:
class Stats {
constructor(stats, circle, budget){
this.stats = stats;
this.circle = circle;
this.budget = budget;
}
addStatsUI(data, budget){
if(data) {
const outcome = Math.round(data * 100) / 100;
const sumAll = Math.round((budget - outcome) * 100) / 100;
this.stats.innerHTML += `
<div><span class="budget-name">Budget: </span> <span class="stat-value">${budget}$</span></div>
<div><span class="budget-name">Outcome: </span> <span class="stat-value outcome-value">${outcome}$</span></div>
<div><span class="budget-name">All: </span> <span class="stat-value last-value">${sumAll}$</span></div>
`;
const circle = Math.round(((outcome * 100) / budget) * 100) / 100;
this.circle.innerHTML += `${circle}%`;
} else {
this.stats.innerHTML = '';
this.circle.innerHTML = '';
}};
类统计信息{
构造函数(统计、循环、预算){
this.stats=stats;
这个圆=圆;
这个.预算=预算;
}
addStatsUI(数据、预算){
如果(数据){
常量结果=数学四舍五入(数据*100)/100;
const sumAll=数学四舍五入((预算-结果)*100)/100;
this.stats.innerHTML+=`
预算:${Budget}$
结果:${output}$
全部:${sumAll}$
`;
常数圆=数学圆(((结果*100)/预算)*100)/100;
this.circle.innerHTML+=`${circle}%`;
}否则{
this.stats.innerHTML='';
this.circle.innerHTML='';
}};
})
导出默认统计信息
好的,a对我的代码进行了一些改进,但订阅方面仍然存在问题。现在一切正常,但当我注销并登录函数getProducts()和updateBudget()时,不会取消订阅 代码如下: index.js:
//get the products and render
const unsubscribe = products.getProducts((data, id) => {
console.log(data, id);
productUI.render(data, id);
}, user.uid);
callbacks.push(unsubscribe);
//update budget + form
const handleBudgetFormSubmit = e => {
e.preventDefault();
//update budget
const budget = Number(budgetForm.budget_value.value.trim());
sumStats.addStatsUI('', '');
products.updateBudget(budget, user.uid);
//reset form
budgetForm.reset();
const budgetCart = document.querySelector('#budget');
budgetCart.classList.remove('active');
// show message
updateMssg.innerText = `Your budget was updated to ${budget}$`;
updateMssg.classList.add('act');
setTimeout(() => {
updateMssg.innerText = '';
updateMssg.classList.remove('act');
}, 3000);
};
budgetForm.addEventListener('submit', handleBudgetFormSubmit);
callbacks.push(() =>
budgetForm.removeEventListener('submit', handleBudgetFormSubmit)
);
如果(用户):
}
});
getProducts()和updateBudget():
}
当我注销并登录时:
当我有了getProducts并将product添加到集合中时,此函数将渲染(render())product两次,但将其添加到集合中一次。当我更新预算时,返回该预算,但之后返回0(在DOM上,ShowBudget a可以看到“Infinity”)
还有一件事,当我注销时,控制台返回错误:
TypeError: callback is not a function
at eval (index.js:182)
at Array.forEach (<anonymous>)
at Object.eval [as next] (index.js:182)
at eval (index.cjs.js:1226)
at eval (index.cjs.js:1336)
TypeError:回调不是函数
评估时(索引js:182)
在Array.forEach()处
在Object.eval[as next](index.js:182)
评估时(索引:1226)
评估时(索引:1336)
我认为这是因为getProducts和updateBudget不返回unsubscribe,而是未定义
也许有人能解决这个问题?好的,对我的代码进行一些改进,但订阅方面仍然存在问题。现在一切正常,但当我注销并登录函数getProducts()和updateBudget()时,不会取消订阅 代码如下: index.js:
//get the products and render
const unsubscribe = products.getProducts((data, id) => {
console.log(data, id);
productUI.render(data, id);
}, user.uid);
callbacks.push(unsubscribe);
//update budget + form
const handleBudgetFormSubmit = e => {
e.preventDefault();
//update budget
const budget = Number(budgetForm.budget_value.value.trim());
sumStats.addStatsUI('', '');
products.updateBudget(budget, user.uid);
//reset form
budgetForm.reset();
const budgetCart = document.querySelector('#budget');
budgetCart.classList.remove('active');
// show message
updateMssg.innerText = `Your budget was updated to ${budget}$`;
updateMssg.classList.add('act');
setTimeout(() => {
updateMssg.innerText = '';
updateMssg.classList.remove('act');
}, 3000);
};
budgetForm.addEventListener('submit', handleBudgetFormSubmit);
callbacks.push(() =>
budgetForm.removeEventListener('submit', handleBudgetFormSubmit)
);
如果(用户):
}
});
getProducts()和updateBudget():
}
当我注销并登录时:
当我有了getProducts并将product添加到集合中时,此函数将渲染(render())product两次,但将其添加到集合中一次。当我更新预算时,返回该预算,但之后返回0(在DOM上,ShowBudget a可以看到“Infinity”)
还有一件事,当我注销时,控制台返回错误:
TypeError: callback is not a function
at eval (index.js:182)
at Array.forEach (<anonymous>)
at Object.eval [as next] (index.js:182)
at eval (index.cjs.js:1226)
at eval (index.cjs.js:1336)
TypeError:回调不是函数
评估时(索引js:182)
在Array.forEach()处
在Object.eval[as next](index.js:182)
评估时(索引:1226)
评估时(索引:1336)
我认为这是因为getProducts和updateBudget不返回unsubscribe,而是未定义
也许有人能解决这个问题?大家好,欢迎光临!我无法理解到底是什么问题。从代码来看,似乎每次添加产品时都会调用sumPrices。另一方面,这似乎也是一个问题。。。它应该如何工作比…?每次当我添加或删除数据表与费用(看屏幕截图)这使sumPrices()但应用程序做代码sumPrices()这样:当我添加一个产品,使一次,添加另一个产品,使两次,添加另一个产品使三等。这发生在相同的方式删除数据。当这种情况发生时,回报率将上升。第一次:返回结果一次,下一次返回两次等。如果这还不够,我可以制作视频,它是如何工作的。你有一个订阅,你没有取消订阅,例如每次你调用
getProducts
它都会创建一个新订阅,我必须在其中放置“取消订阅”来修复它?在函数或index.js中获取产品@Reza@mGryska两种方法:您可以调用getProducts一次,该函数需要返回observable,您订阅它,然后当您的组件正在销毁时,您需要取消订阅,另一种方法是在管道中使用first()
,它将结束订阅,并且每次您都可以调用getProductsHi并欢迎!我无法理解到底是什么问题。从代码来看,似乎每次添加产品时都会调用sumPrices。另一方面,这似乎也是一个问题。。。它应该如何工作比…?每次当我添加或删除数据表与费用(看屏幕截图)这使sumPrices()但应用程序做代码sumPrices()这样:当我添加一个产品,使一次,添加另一个产品,使两次,添加另一个产品使三等。这发生在相同的方式删除数据。当这种情况发生时,回报率将上升。第一次:返回结果一次,下一次返回两次等。如果这还不够,我可以制作视频,它是如何工作的。你有一个订阅,你没有取消订阅,例如每次你调用getProducts
它都会创建一个新订阅,我必须在其中放置“取消订阅”来修复它?在函数或index.js中获取产品@Reza@mGryska两种方法:您可以调用getProducts一次,该函数需要返回observable,您订阅了它,然后当您的组件正在销毁时,您需要取消订阅,另一种方法是在管道中使用first()
,它将结束订阅,并且每次您都可以调用getProducts