MODUL 4 - LEKCIJA 2

Napredni HTML Helpers i Partial Views

Partial Views, Child Actions i napredni HTML Helpers

⏱️ Trajanje: ~3 časa 📚 Nivo: Srednji 🎯 Praktični primjeri: 5

📖 Partial Views i Arhitektura Komponenti

Partial Views (djelomični view-ovi) su fragmenti korisničkog interfejsa dizajnirani za ponovnu upotrebu na više različitih stranica (reusability). Ako razvijete složenu formu za unos podataka o građaninu, smještanjem te forme u Partial View omogućavate njeno korištenje i na stranici "Nova Prijava" i na stranici "Ažuriraj Profil".

🔑 Performansna Razlika: Html.Partial vs. Html.RenderPartial

  • Html.Partial("_Naziv"): Kompajlira View, pretvara ga u HTML string i tek onda ubacuje na željeno mjesto. Lakši je za korištenje, ali zauzima memoriju za string objekte na serveru.
  • Html.RenderPartial("_Naziv"): Piše direktno u izlazni stream (HTTP Response Stream) bez kreiranja privremenog stringa u memoriji. U visoko-opterećenim aplikacijama (npr. porezni portali tokom prijava), ovo je preferirana metoda zbog znatno boljih performansi.

Kreiranje Partial View-a

🛠️ _EmployeeCard.cshtml
@* Views/Shared/_MinistryCard.cshtml *@
@model JavnaUprava.Models.Department

@Model.DepartmentName (@Model.DepartmentCode)

Budžet: @Model.Budget.ToString("C")

Broj zaposlenih: @Model.Employees.Count

Renderovanje Partial View-a

🛠️ Korištenje Partial View-a
@* U glavnom view-u (Lista Ministarstava) *@
@foreach (var dept in Model)
{
    @Html.Partial("_MinistryCard", dept)
}

@* ILI koristeći RenderPartial (brže) *@
@foreach (var dept in Model)
{
    Html.RenderPartial("_MinistryCard", dept);
}

🎯 Child Actions (Pod-akcije)

Dok su Partial Views zaduženi isključivo za vizuelizaciju proslijeđenih podataka, Child Actions dozvoljavaju da "komponenta" ima sopstvenu poslovnu logiku koja dobavlja podatke iz baze pre nego sto vrati Partial View.

Često se koriste za widgete: npr. prikaz najnovijih obavijesti u sidebar-u, dinamički navigacijski meni zasnovan na radnom mjestu zaposlenika (Role-Based Access) itd. U novijim tehnologijama (.NET Core / .NET 8), ovo je evoluiralo u koncepte poznate kao ViewComponents.

Glavni View Index.cshtml @Html.Action("Meni") Kontroler MenuController.cs [ChildActionOnly] Baza Partial View _Menu.cshtml 1. Poziva akciju 2. Vraća View 3. Ugrađuje HTML rezultat u glavni prozor

🔒 Sigurnosni Aspekt: [ChildActionOnly]

Ovaj atribut je krucijalan. On zabranjuje korisnicima da direktno pristupe akciji preko URL-a (npr. kucanjem /Menu/SidebarMenu u browseru). Metoda se može pozvati isključivo programski iz roditeljskog (internog) view-a. To podiže nivo sigurnosti sprječavajući neovlašteni pristup i otkrivanje parcijalnih podataka strukture servera.

🛠️ Child Action Primjer
// Controller (CommonController.cs)
[ChildActionOnly]
public ActionResult SidebarMenu()
{
    var departments = db.Departments.ToList();
    return PartialView("_SidebarMenu", departments);
}

// View (Layout)
@Html.Action("SidebarMenu", "Common")

🛠️ Napredni HTML Helpers

1. Html.DisplayFor i Html.EditorFor

🛠️ DisplayFor i EditorFor
@* DisplayFor - samo za prikaz *@
@Html.DisplayFor(m => m.DepartmentName)
@Html.DisplayFor(m => m.Budget)

@* EditorFor - za editovanje *@
@Html.EditorFor(m => m.DepartmentName)
@Html.EditorFor(m => m.DepartmentCode)
@Html.EditorFor(m => m.Budget)

2. Html.ValidationMessageFor

🛠️ Validacija
@Html.TextBoxFor(m => m.Email)
@Html.ValidationMessageFor(m => m.Email, "", new {{ @class = "text-danger" }})

3. Custom HTML Helpers

🛠️ Kreiranje Custom Helpera
// Helpers/StatusHelper.cs
public static class StatusHelper
{
    public static MvcHtmlString StatusLabel(this HtmlHelper helper, bool isActive)
    {
        var tag = new TagBuilder("span");
        tag.AddCssClass(isActive ? "label label-success" : "label label-danger");
        tag.SetInnerText(isActive ? "Aktivan" : "Neaktivan");
        return new MvcHtmlString(tag.ToString());
    }
}

// Korištenje u view-u
@Html.StatusLabel(item.IsActive)

🎯 Praktična Vježba

Zadatak: Kreirajte Meni Ministarstava

Kreirajte Child Action i Partial View koji prikazuje listu svih ministarstava u sidebar-u layout stranice.

✅ Zaključak

Naučili ste: