nmk

Лабораторне заняття №10 (2 години). Створення логічних модулів та обробка бізнес-логіки.

Мета

Створити основний “двигун” інтернет-магазину — кошик покупця. Навчитися прослуховувати події кліку, додавати товари до масиву кошика, створювати функції підрахунку суми та зберігати стан додатку в локальній пам’яті браузера.

План

  1. Створення масиву cart для зберігання товарів у кошику.
  2. Прослуховування подій кліку на кнопках “Купити” (addEventListener).
  3. Використання методів пошуку в масивах (.find()) для знаходження товару за його id.
  4. Написання функції додавання об’єкта товару в масив cart.
  5. Розрахунок загальної вартості кошика за допомогою .reduce().
  6. Оновлення лічильника кошика в Header (інтерфейсі користувача).

Хід роботи

Увага: Продовжуємо роботу у файлі main.js інтернет-магазину “TechShop”. Дані про товари вже виводяться на екран (завдяки ПР №9).

  1. Ініціалізація кошика:
    • Створіть новий порожній масив, який виконуватиме роль кошика: let cart = [];. Зверніть увагу, ми використовуємо let, бо товари в ньому будуть змінюватись.
  2. Обробка кліків (Event Listeners):
    • У нас є згенеровані раніше дочірні кнопки: <button class="btn btn-buy" data-id="${product.id}">.
    • Замість того, щоб вішати eventListener на КОЖНУ з 100 кнопок (що дуже ресурсоємно), використаємо “Делегування подій” (Event Delegation).
    • Повісьте обробник подій на весь контейнер: document.querySelector('.products-grid').addEventListener('click', ...)
  3. Логіка кнопки “Купити”:
    • Усередині функції обробника, перевірте, чи був клік саме по кнопці (а не по картинці):

      const container = document.querySelector(".products-grid");
      
      container.addEventListener("click", (event) => {
        // Якщо клік був на елементі з класом 'btn-buy'
        if (event.target.classList.contains("btn-buy")) {
          // 1. Отримуємо ID товару з data-атрибута кнопки (рядок конвертуємо в число)
          const productId = Number(event.target.dataset.id);
      
          // 2. Шукаємо весь об'єкт товару в оригінальному масиві `products`
          const selectedProduct = products.find((p) => p.id === productId);
      
          // 3. Додаємо в Кошик
          addToCart(selectedProduct);
        }
      });
      
  4. Функція додавання до кошика:
    • Напишіть функцію addToCart(product). Вона повинна пересвідчитись, чи цей товар ВЖЕ Є в масиві cart.

      function addToCart(product) {
        // Перевіряємо (через метод find) чи існує вже такий товар
        const existingItem = cart.find((item) => item.id === product.id);
      
        if (existingItem) {
          // Якщо товар вже в кошику, просто збільшуємо кількість у властивості `quantity`
          existingItem.quantity += 1;
        } else {
          // Інакше додаємо новий об'єкт у масив, встановлюючи початкову кількість = 1 (Spread оператор)
          cart.push({ ...product, quantity: 1 });
        }
      
        updateUI(); // Викликаємо оновлення екрану
      }
      
  5. Обробка Бізнес-Логіки (Підрахунок суми):
    • Напишіть функцію calculateTotal(), яка обчислює загальну вартість кошика. Найкраще для цього підходить метод .reduce():
      function calculateTotal() {
        return cart.reduce(
          (total, item) => total + item.price * item.quantity,
          0,
        );
      }
      
  6. Оновлення Інтерфейсу (UI):
    • Напишіть функцію updateUI(), яка змінить цифру біля іконки кошика в <header> та виведе в console.log() розраховану загальну суму.

      function updateUI() {
        const cartCounter = document.querySelector(".cart-counter");
        // Практично так само метод reduce для рахунку загальної кількості товарів (включаючи > 1 одного типу)
        const totalItems = cart.reduce((sum, item) => sum + item.quantity, 0);
      
        if (cartCounter) {
          cartCounter.textContent = totalItems;
        }
      
        console.log("Поточний кошик:", cart);
        console.log("Загальна сума:", calculateTotal(), "грн");
      }
      
  7. Збереження (Commit & Push):
    • Натисніть “Купити” на кількох товарах. Відкрийте Console у DevTools і подивіться, як змінюється кошик і сума.
    • Виконайте git add . та git commit -m "Implement Core Shopping Cart Logic and Total Calculation".
    • Запушіть у свою гілку та злийте в main.

Результат

Магазин “TechShop” набув бізнес-логіки. Тепер він вміє зберігати стан поточних покупок клієнта в пам’яті комп’ютера (RAM), обробляти кліки та миттєво рахувати складні дані, такі як кількість усіх одиниць і вартість кошика.

Контрольні питання

  1. В чому суть патерна “Делегування подій” (Event Delegation) у порівнянні з розвішуванням addEventListener на 100 кнопок окремо? Які об’єкти / методи JavaScript роблять це можливим?
  2. Якими методами можна знайти елемент в масиві за якоюсь властивістю (напр. по ID)? Яка між ними різниця?
  3. Що таке Spread-оператор (...) і навіщо ми використали { ...product, quantity: 1 } при додаванні нового товару в кошик? Що буде, якщо ми не використаємо Spread?
  4. Опишіть словами аргументи функції reduce((total, item) => total + item.price, 0). Що таке total, звідки він береться і навіщо потрібен , 0 у кінці?
  5. Змінна let cart = [] зберігає дані під час запуску скрипта. Що станеться, якщо користувач натисне F5 (Оновити сторінку)? Чи залишиться інформація? Як розв’язати цю проблему у браузері?