Trudny / egzaminacyjny · lekcja 22
Projekt 3: Sklep internetowy (e-sklep) — katalog, wyszukiwanie i koszyk
Podstawa programowa INF.04.7.3 wprost wymienia "funkcjonalności e-sklepu" jako jeden z typów aplikacji, które powinieneś umieć zaprogramować. Ten projekt buduje WŁAŚNIE to — prawdziwy, kompletny sklep internetowy z katalogiem produktów podzielonym na kategorie...
Zacznij tutaj
Po co się tego uczymy?
Wprowadzenie
Teoria
Wymagania projektu:
- Katalog produktów podzielony na kategorie, z możliwością filtrowania po kategorii;
- Wyszukiwarka — pole tekstowe filtrujące produkty po nazwie NA BIEŻĄCO, w miarę pisania;
- Koszyk — dodawanie produktów, zmiana ilości, usuwanie pozycji, widoczny na każdej stronie licznik produktów w koszyku;
- Podsumowanie zamówienia i "checkout" — ekran z listą zamówionych produktów, sumą do zapłaty, i formularzem danych do wysyłki (imię, adres) z walidacją.
Wyszukiwanie NA BIEŻĄCO — debounceTime. Filtrowanie produktów przy KAŻDYM naciśnięciu klawisza (bez czekania na kliknięcie przycisku "Szukaj") to standardowa funkcjonalność e-sklepu. Naiwna implementacja wysyłałaby żądanie do backendu przy KAŻDEJ literze — marnując zasoby. RxJS (biblioteka używana wewnętrznie przez Angular, poznana pobieżnie przy Observable w lekcji 12) udostępnia operator debounceTime(300), który CZEKA 300 milisekund od OSTATNIEGO naciśnięcia klawisza, zanim faktycznie wykona wyszukiwanie — jeśli użytkownik pisze dalej, poprzednie oczekiwanie jest anulowane. Efekt: żądanie wysyłane jest dopiero, gdy użytkownik faktycznie PRZESTANIE pisać (choćby na chwilę), a nie po każdej literze.
Filtrowanie po stronie backendu (query string). Zamiast pobierać WSZYSTKIE produkty i filtrować je w Angularze (co przy dużym katalogu byłoby nieefektywne), backend przyjmuje parametry zapytania: GET /api/produkty?kategoria=elektronika&szukaj=klawiatura — kontroler odczytuje je jako zwykłe parametry metody C# (ASP.NET Core SAM mapuje parametry query string na parametry akcji o tej samej nazwie) i filtruje zapytanie LINQ/EF Core PRZED wysłaniem wyniku.
Koszyk jako serwis Angular (dokładnie ten wzorzec z lekcji 10 i projektu restauracji, lekcja 23) — KoszykService przechowuje aktualnie dodane produkty i ich ilości, udostępnia metody dodaj(), usun(), obliczSume(), i jest wstrzykiwany zarówno w komponent nagłówka (pokazujący licznik), jak i w komponent samego koszyka/checkout.
Zobacz zależności
Schemat
KatalogComponent
<input [(ngModel)]="fraza" (ngModelChange)="naZmianeSzukania($event)">
│
│ RxJS: this.szukajZmiana$.pipe(debounceTime(300)).subscribe(...)
▼
GET /api/produkty?kategoria=X&szukaj=Y
│
▼
ASP.NET Core: ProduktyController.GetWszystkie(string? kategoria, string? szukaj)
│
├── query = context.Produkty.AsQueryable();
├── if (kategoria != null) query = query.Where(p => p.Kategoria == kategoria);
├── if (szukaj != null) query = query.Where(p => p.Nazwa.Contains(szukaj));
│
▼
return Ok(await query.ToListAsync());
KoszykService (singleton)
dodaj(produkt) / usun(id) / obliczSume()
│ │
▼ ▼
NaglowekComponent KoszykComponent (checkout)
(licznik produktów) (lista + suma + formularz danych wysyłki)
Połącz z praktyką
Przykład z życia
Każdy sklep internetowy (Allegro, Amazon, mniejsze sklepy branżowe) działa dokładnie na tej zasadzie: katalog z kategoriami i wyszukiwarką, koszyk widoczny w nagłówku niezależnie od tego, którą podstronę akurat przeglądasz, i finalne podsumowanie przed złożeniem zamówienia — to jeden z najbardziej rozpoznawalnych i praktycznych wzorców w całym świecie aplikacji webowych.