Trudny / egzaminacyjny · lekcja 25

Projekt 6: Serwis ogłoszeniowy — dodawanie, wyszukiwanie i filtrowanie

Trzecia z czterech funkcjonalności nazwanych wprost w podstawie programowej (INF.04.7.3) — serwis ogłoszeniowy (jak OLX czy Otomoto). Ten projekt ćwiczy zaawansowane filtrowanie WIELOMA kryteriami naraz (kategoria, cena od-do, lokalizacja) oraz sortowanie wyni...

Zacznij tutaj

Po co się tego uczymy?

Trzecia z czterech funkcjonalności nazwanych wprost w podstawie programowej (INF.04.7.3) — serwis ogłoszeniowy (jak OLX czy Otomoto). Ten projekt ćwiczy zaawansowane filtrowanie WIELOMA kryteriami naraz (kategoria, cena od-do, lokalizacja) oraz sortowanie wyników — umiejętności przydatne w niemal każdej aplikacji z większym katalogiem danych.

Wprowadzenie

Teoria

Wymagania projektu:

  • Dodawanie ogłoszenia — WYMAGA zalogowania; tytuł, opis, cena, kategoria, zdjęcie (upload, lekcja 18);
  • Wyszukiwanie i filtrowanie WIELOMA kryteriami naraz: kategoria, zakres cenowy (od-do), fraza w tytule/opisie;
  • Sortowanie wyników: od najnowszych, od najtańszych, od najdroższych;
  • Szczegóły ogłoszenia z danymi kontaktowymi do wystawiającego (widoczne np. dopiero po zalogowaniu — ochrona przed botami zbierającymi dane kontaktowe);
  • "Moje ogłoszenia" — lista WŁASNYCH ogłoszeń zalogowanego użytkownika, z możliwością edycji/usunięcia/oznaczenia jako "sprzedane".

Filtrowanie wieloma kryteriami naraz — budowanie zapytania KROK PO KROKU. Rozszerzenie techniki z projektu sklepu (lekcja 22, filtrowanie po kategorii i frazie) o WIĘCEJ warunków, dokładanych WARUNKOWO (tylko jeśli dany filtr został ustawiony przez użytkownika):

var zapytanie = context.Ogloszenia.AsQueryable();
if (kategoria != null) zapytanie = zapytanie.Where(o => o.Kategoria == kategoria);
if (cenaOd.HasValue) zapytanie = zapytanie.Where(o => o.Cena >= cenaOd.Value);
if (cenaDo.HasValue) zapytanie = zapytanie.Where(o => o.Cena <= cenaDo.Value);
if (fraza != null) zapytanie = zapytanie.Where(o =>
    o.Tytul.Contains(fraza) || o.Opis.Contains(fraza));

Każdy if DOKŁADA kolejny warunek do TEGO SAMEGO obiektu zapytania — dopiero ostatnie wywołanie (.OrderBy(...).ToListAsync()) faktycznie generuje i wykonuje JEDNO zapytanie SQL łączące WSZYSTKIE ustawione filtry przez AND.

Sortowanie dynamiczne — wybór kolumny w czasie działania. Parametr sortuj (np. "cena_rosnaco", "cena_malejaco", "data") decyduje, jakiej metody OrderBy/OrderByDescending użyć — realizowane przez proste wyrażenie switch zwracające odpowiednio posortowane zapytanie.

Formularz filtrów w Angularze — grupa kontrolek Reactive Forms. Zamiast osobnych zmiennych na każdy filtr, wygodnie jest zebrać WSZYSTKIE kryteria w jeden FormGroup (poznany w lekcji 11) — zmiana KTÓREGOKOLWIEK pola filtra (przez subskrypcję formularz.valueChanges) automatycznie wywołuje nowe zapytanie do backendu z aktualnym zestawem filtrów.

Zobacz zależności

Schemat

FormGroup filtrow = { kategoria, cenaOd, cenaDo, fraza, sortuj }
        │
        │  formularzFiltrow.valueChanges.subscribe(wartosci => pobierzOgloszenia(wartosci))
        ▼
GET /api/ogloszenia?kategoria=X&cenaOd=100&cenaDo=500&fraza=rower&sortuj=cena_rosnaco
        │
        ▼
ASP.NET Core: budowanie zapytania KROK PO KROKU
  zapytanie = context.Ogloszenia.AsQueryable()
  if kategoria    → .Where(kategoria)
  if cenaOd       → .Where(cena >= cenaOd)
  if cenaDo       → .Where(cena <= cenaDo)
  if fraza        → .Where(tytul/opis zawiera fraza)
  switch sortuj   → .OrderBy(...) / .OrderByDescending(...)
        │
        ▼
  JEDNO zapytanie SQL z wszystkimi warunkami (AND) → wynik do Angular

Połącz z praktyką

Przykład z życia

Serwisy takie jak OLX czy Otomoto pozwalają zawęzić tysiące ogłoszeń do garstki pasujących wyników przez kombinację filtrów (kategoria, cena, lokalizacja, słowo kluczowe) — to jeden z najbardziej praktycznych, codziennych przykładów zaawansowanego wyszukiwania w aplikacjach webowych, a ten projekt buduje uproszczoną, ale strukturalnie prawdziwą wersję tego mechanizmu.