首页 > 解决方案 > 为什么添加商品的方法不正确?

问题描述

当 add 方法的监听器 "buttAdd.addEventListener" 被触发时: ,首先这个条件工作几次(与第二个加法一起工作):

if (inputsAdd [0].value ===""||inputsAdd [1].value ===""||inputsAdd [2]
.value === "") 
{alert ("fill all fields");}

它在字段不为空时起作用,然后添加产品。如果您单击带有空白字段的添加按钮,那么之前添加的产品 - 将会丢失。方法相同,删除。请帮我修复它

//Product Creation Class
class Product {
    constructor(name, count, price) {
        this.name = name;
        this.count = count;
        this.price = price;
    }
}
Product.SORT_ORDER_ASC = 1;
Product.SORT_ORDER_DESC = -1;
// Сlass where products are recorded
class Shop {
    constructor() {
        this.products = [];
        this.formAdd = document.forms[0];
        this.inputsAdd = this.formAdd.elements;
        this.buttAdd = this.formAdd.elements[3];
        this.formDelete = document.forms[1];
        this.nameDelete = this.formDelete.elements[0];
        this.buttDelete = this.formDelete.elements[1];

    }

    //method for adding a product
    addProduct(newProduct) {
        this.products.push(newProduct);
    }

    //method for remove product by name
    deleteProductByName(productName) {
        let i = this.products.length;
        while (i--) {
            if (productName === this.products[i].name) {
                this.products.splice(i, 1);
            }
        }
    }

    // get total price by all products
    get totalProductsPrice() {
        return this.products.map(product => product.price).reduce((p, c) => p + c);
    }

    //method for sorting the product at its price
    sortProductsByPrice(sortOrder) {
        const sorted = this.products.sort((a, b) => {
            return a.price > b.price ? sortOrder : -sortOrder;
        });
        this.products = sorted;
    }

    // method to draw the table with product property (
    // name, count, price)
    show() {
        // add new product by click
        this.buttAdd.addEventListener('click', (e) => {
            e.preventDefault();
            if (this.inputsAdd[0].value === "" || this.inputsAdd[1].value === "" || this.inputsAdd[2].value === "") {
                alert("fill all fields");
            } else {
                this.addProduct(new Product(this.inputsAdd[0].value, parseInt(this.inputsAdd[2].value),
                    parseInt(this.inputsAdd[1].value)));
                this.show();
                this.inputsAdd[0].value = "";
                this.inputsAdd[1].value = "";
                this.inputsAdd[2].value = "";
            }
        }, false);
        // delete product by name after click
        this.buttDelete.addEventListener('click', (e) => {
            e.preventDefault();
            if (this.nameDelete.value === "") {
                alert("write a name of product what you want to delete");
            } else {
                this.deleteProductByName(this.nameDelete.value);
                this.show();
                this.nameDelete.value = "";
            }

        }, false);
        const rows = document.querySelectorAll("#shop .data");
        for (let i = rows.length - 1; i >= 0; i--) {
            const e = rows.item(i);
            e.parentNode.removeChild(e);
        }
        const table = document.getElementById("shop");
        const tFoot = table.querySelector('tfoot');
        if (tFoot) tFoot.remove();

        for (let i = 0; i < this.products.length; i++) {
            //create table
            table.innerHTML += `<tbody><tr class="data"><td>${this.products[i].name}</td>
    <td>${this.products[i].price}</td>
    <td>${this.products[i].count}</td></tr></tbody>`;
        }
        //show total price by all products
        table.innerHTML += `<tfoot><tr><td colspan="3" id="total-price">Total price: 
        ${this.totalProductsPrice}</td></tr></tfoot>`;

//filter products by price
        document.addEventListener("click", (e) => {
            let elem = e.target;
            if (elem.id === "filter") {
                this.sortProductsByPrice(Product.SORT_ORDER_ASC);
                this.show();
            }
        }, false);
        console.log(this.products);
    }
}

let shop = new Shop();
shop.addProduct(new Product("product", 1, 2000));
shop.addProduct(new Product("product1", 2, 500));
shop.addProduct(new Product("product2", 3, 1000));
shop.show();
<div class="Shop">
    <div class="add-product">
        <h1>Add product</h1>
        <form id="addForm">
            <label for="name" >Name of product</label>
            <input type="text"  id="name" class="input-product">
            <label for="price">Price of product</label>
            <input type="text"  id="price" class="input-product">
            <label for="count">Count of product</label>
            <input type="text"  id="count" class="input-product">
            <button id="add" type="button">Add</button><!-- *** -->
        </form>
    </div>
    <div class="product-table">
        <h2>Products</h2>
        <form id="delete-form">
            <label for="name-delete">Delete product by name</label>
            <input type="text" id="name-delete" class="input-delete">
            <button id="delete" type="button">Delete</button>
        </form>
        <table id="shop">
            <caption>Products that are available in the store</caption>
            <tr>
                <th>Name:</th>
                <th id="filter">Price:</th>
                <th>Count:</th>
            </tr>
        </table>
    </div>
</div>

标签: javascriptdomecmascript-6

解决方案


看,你正在定义let shop = new Shop()然后在你的 Shop 类中使用这个变量,比如shop.show(). 我强烈建议您使用this关键字而不是作用域变量(对所有其他shop用法条目有效)。

现在,关于

工作几次

我假设,当您调用该show()方法时,它会在一段时间内注册更多事件侦听器。我的意思是,你打电话show- 它会创建新的事件监听器 + 有时会调用自己(嗯,这很冒险)。我建议您将侦听器声明移动到构造函数 - 这样它们将被实例化一次(但这需要保留 DOM 节点)。此外,最好将您的显示功能拆分为几个较小的功能并摆脱自我功能发射(它将降低复杂性)。


推荐阅读