【发布时间】:2021-10-05 15:09:59
【问题描述】:
我正在制作一个列表,您可以在其中编辑或删除项目。我正在同一张桌子上听 2 个事件。一个用于编辑,一个用于删除,我正在听表格而不是实际按钮,因为它们是动态创建的。 Edit 和 Delete 都具有相同的 id,即产品的 id,我稍后将其用于 http 请求。 , 现在,当我按下编辑时,删除功能中的 console.logs 会启动,但没有任何反应,如果我试图保存项目,http 请求不起作用,它不会使用 id(但会将其记录到控制台)
如果我按下删除按钮一次没有发生任何事情,如果我第二次按下它,页面会刷新并删除项目。
有没有办法单独监听这些事件或让它们不相互干扰?我想要的只是如果我按下编辑按钮将相应项目的值转到输入字段,当我按下添加项目时也更新 JSON 文件中的产品,并在删除按下时从 JSON 文件中删除项目和从 html 文档中删除。
更新:设法解决编辑功能
这是我的代码:
import { http } from "./http.js";
import { ui } from "./ui.js";
const productsURL = "https://61363d1a8700c50017ef54c1.mockapi.io/product";
// const addProductBtn = document.querySelector('.new-product-btn');
const adminContainer = document.querySelector('.admin-container');
const addItem = document.querySelector('.admin-add-item-btn');
const imgInput = document.getElementById('image');
const nameInput = document.getElementById('name');
const priceInput = document.getElementById('price');
const stockInput = document.getElementById('stock');
const categoryInput = document.getElementById('category');
const typeInput = document.getElementById('type');
const descriptionInput = document.getElementById('description');
const validSvg = document.querySelectorAll('.valid_input_svg');
// const adminForm = document.getElementById('admin-form');
const adminTable = document.getElementById('admin-tbody');
const editBtn = document.querySelectorAll('.edit-btn');
const adminBtn = document.querySelectorAll('.admin-delete-btn');
const cancel = document.getElementById('cancel');
let productToEdit;
let edit = false;
let id;
document.addEventListener('DOMContentLoaded', listAdminProducts);
// adminForm.addEventListener('submit', validateInput);
addItem.addEventListener('click', addOrEditProducts);
// adminTable.addEventListener('click', editOrDeleteItem);
adminTable.addEventListener('click', deleteProduct);
adminTable.addEventListener('click', editProduct);
cancel.addEventListener('click', cancelEdit);
function listAdminProducts() {
http.get(productsURL).then(products => {
ui.showAllAdminProducts(products);
});
};
function addOrEditProducts() {
if (edit === true && validateInput() === true) {
productToEdit = {
image: imgInput.value,
name: nameInput.value,
price: priceInput.value,
stock: stockInput.value,
category: categoryInput.value,
type: typeInput.value,
description: descriptionInput.value,
};
http
.put(`${productsURL}/${id}`, productToEdit)
.then(() => listAdminProducts());
console.log(`${productsURL}/${id}`)
ui.clearFields();
id = '';
edit = false;
return;
} else if (edit === false && validateInput() === true) {
const product = {
image: imgInput.value,
name: nameInput.value,
price: priceInput.value,
stock: stockInput.value,
category: categoryInput.value,
type: typeInput.value,
description: descriptionInput.value
};
http.post(productsURL, product).then(() => listAdminProducts());
ui.clearFields();
};
};
function editProduct(e) {
console.log('works');
if (e.target.classList.contains('edit-btn')) {
edit = true;
id = e.target.getAttribute('id');
console.log(id);
console.log(e.target)
http.get(`${productsURL}/${id}`).then((data) => {
imgInput.value = data.image;
nameInput.value = data.name;
priceInput.value = data.price;
stockInput.value = data.stock;
categoryInput.value = data.category;
typeInput.value = data.type;
descriptionInput.value = data.description;
});
console.log(`${productsURL}/${id}`)
};
// id = '';
}
function deleteProduct(e) {
console.log(e.target);
if (e.target.className === 'admin-delete-btn') {
console.log(e.target);
id = e.target.getAttribute('id');
console.log(id);
http
.delete(`${productsURL}/${id}`)
.then(() => listAdminProducts())
.catch("Error on delete");
id = '';
}
ui.showSuccessMessage('Product deleted', adminContainer);
}
function cancelEdit() {
ui.clearFields;
imgInput.className = '';
nameInput.className = '';
priceInput.className = '';
stockInput.className = '';
categoryInput.className = '';
edit = false;
}
function validateInput() {
let valid = true;
if (imgInput.value == '') {
if (imgInput.classList.contains('input-invalid')) {
imgInput.classList.remove('input-invalid');
};
ui.showAdminMessage('Must contain a link to an image', 0);
imgInput.classList.add('input-invalid');
valid = false;
} else {
imgInput.classList.add('input-valid');
validSvg[0].style.display = "block";
removeClass(imgInput, 0);
};
if (nameInput.value === '') {
if (nameInput.classList.contains('input-invalid')) {
nameInput.classList.remove('input-invalid');
};
ui.showAdminMessage('Name is requierd', 1);
nameInput.classList.add('input-invalid');
valid = false;
} else {
// stockInput.classList.remove('input-invalid');
nameInput.classList.add('input-valid');
validSvg[1].style.display = "block";
removeClass(nameInput, 1);
};
if (priceInput.value == "" || isNaN(priceInput.value) || priceInput.value < 0) {
if (priceInput.classList.contains('input-invalid')) {
priceInput.classList.remove('input-invalid');
};
ui.showAdminMessage('Price must be a number greater then 0', 2);
priceInput.classList.add('input-invalid');
valid = false;
} else {
// stockInput.classList.remove('input-invalid');
priceInput.classList.add('input-valid');
validSvg[2].style.display = "block";
removeClass(priceInput, 2);
};
if (stockInput.value == "" || isNaN(stockInput.value) || stockInput.value < 0) {
if (stockInput.classList.contains('input-invalid')) {
stockInput.classList.remove('input-invalid');
};
ui.showAdminMessage('Stock must be a number greater then 0', 3);
stockInput.classList.add('input-invalid');
valid = false;
} else {
// stockInput.classList.remove('input-invalid');
stockInput.classList.add('input-valid');
validSvg[3].style.display = "block";
removeClass(stockInput, 3);
};
if (categoryInput.value === 'barware' || categoryInput.value === 'spirits') {
// categoryInput.classList.remove('input-invalid');
categoryInput.classList.add('input-valid');
validSvg[4].style.display = "block";
removeClass(categoryInput, 4);
} else {
ui.showAdminMessage('Category must be barware or spirits', 4);
categoryInput.classList.add('input-invalid');
valid = false;
};
return valid;
};
function removeClass(element, index) {
// console.log(element, index);
setTimeout(() => {
element.className = '';
validSvg[index].style.display = "none";
}, 3000)
}
【问题讨论】:
-
嗯,您是否意识到您在 if 语句之外还有代码?就像
ui.showSuccessMessage('Product deleted', adminContainer);不管你是否点击删除按钮都会运行。 -
退出
function deleteProduct(e) { if (!e.target.closest('.admin-delete-btn')) return; -
Edit 和 Delete 都具有相同的 id。 ID 应该是唯一的。您应该将产品 ID 放在
data-XXX属性中。 -
是的,我知道它们具有相同的 id,它们具有产品的 id,我在 http 请求中使用它,但它们在函数中被重置。我将尝试将 id 放在数据值属性中
标签: javascript json function httprequest eventhandler