Zobrazení komponent v ASP.NET Core

Autor: Rick Anderson

Komponenty zobrazení

Komponenty zobrazení se podobají částečným zobrazením, ale jsou mnohem výkonnější. Komponenty zobrazení nepoužívají vazbu modelu, závisí na datech předaných při volání komponenty zobrazení. Tento článek byl napsán pomocí kontrolerů a zobrazení, ale komponenty zobrazení fungují se stránkamiRazor.

Součást zobrazení:

  • Vykreslí blok dat místo celé odpovědi.
  • Zahrnuje stejné výhody oddělení a testovatelnosti, které byly nalezeny mezi kontrolerem a zobrazením.
  • Může mít parametry a obchodní logiku.
  • Obvykle je vyvolána ze stránky rozložení.

Součásti zobrazení jsou určené kdekoli opakovaně použitelná logika vykreslování, která je pro částečné zobrazení příliš složitá, například:

  • Dynamické navigační nabídky
  • Označování cloudu, kde se dotazuje databáze
  • Panel Přihlášení
  • Nákupní košík
  • Nedávno publikované články
  • Obsah bočního panelu na blogu
  • Přihlašovací panel, který by se vykresloval na každé stránce a zobrazoval odkazy pro odhlášení nebo přihlášení v závislosti na stavu přihlášení uživatele

Součást zobrazení se skládá ze dvou částí:

  • Třída, obvykle odvozená z ViewComponent
  • Výsledek, který vrátí, obvykle zobrazení.

Podobně jako kontrolery může být komponenta zobrazení POCO, ale většina vývojářů využívá metody a vlastnosti, které jsou k dispozici odvozením z ViewComponent.

Při zvažování, jestli komponenty zobrazení splňují specifikace aplikace, zvažte místo toho použití Razor komponent. Razor komponenty také kombinují značky s kódem jazyka C#, aby se vytvořily opakovaně použitelné jednotky uživatelského rozhraní. Razor komponenty jsou navržené pro produktivitu vývojářů při poskytování logiky a složení uživatelského rozhraní na straně klienta. Další informace najdete v tématu ASP.NET základní Razor komponenty. Informace o tom, jak začlenit Razor komponenty do aplikace MVC nebo Razor Pages, najdete v tématu Integrace komponent ASP.NET Core Razor do aplikací ASP.NET Core.

Vytvoření komponenty zobrazení

Tato část obsahuje požadavky vysoké úrovně pro vytvoření komponenty zobrazení. Později v článku podrobně prozkoumáme jednotlivé kroky a vytvoříme součást zobrazení.

Třída komponenty view

Třídu komponenty zobrazení lze vytvořit některou z následujících možností:

Podobně jako kontrolery musí být součásti zobrazení veřejné, vnořené a ne abstraktní třídy. Název komponenty zobrazení je název třídy s odebranou příponou ViewComponent . Lze ho Name také explicitně zadat pomocí vlastnosti.

Třída komponenty view:

  • Podporuje injektáž závislostí konstruktoru .
  • Neúčastní se životního cyklu kontroleru, proto se filtry nedají použít v komponentě zobrazení.

Chcete-li zabránit třídě, která má příponu nerozlišující ViewComponent malá a velká písmena, aby byla považována za součást zobrazení, ozdobte třídu atributem [NonViewComponent] :

using Microsoft.AspNetCore.Mvc;

[NonViewComponent]
public class ReviewComponent
{
    public string Status(string name) => JobStatus.GetCurrentStatus(name);
}

Zobrazení metod komponent

Komponenta zobrazení definuje svou logiku v:

  • InvokeAsync metoda, která vrací Task<IViewComponentResult>.
  • Invoke synchronní metoda, která vrací hodnotu IViewComponentResult.

Parametry pocházejí přímo z vyvolání komponenty zobrazení, nikoli z vazby modelu. Komponenta zobrazení nikdy přímo nezpracuje požadavek. Komponenta zobrazení obvykle inicializuje model a předává ho do zobrazení voláním View metody. V souhrnu zobrazte metody komponent:

  • Definujte metodu InvokeAsyncTask<IViewComponentResult>, která vrací nebo synchronní Invoke metodu, která vrací .IViewComponentResult
  • Obvykle inicializuje model a předá ho do zobrazení voláním ViewComponent.View metoda.
  • Parametry pocházejí z volající metody, nikoli HTTP. Neexistuje žádná vazba modelu.
  • Není dostupný přímo jako koncový bod HTTP. Obvykle se vyvolávají v zobrazení. Komponenta zobrazení nikdy nezpracuje požadavek.
  • Jsou přetíženy u podpisu místo jakýchkoli podrobností z aktuálního požadavku HTTP.

Zobrazit cestu hledání

Modul runtime hledá zobrazení v následujících cestách:

  • /Views/{Controller Name}/Components/{View Component Name}/{View Name}
  • /Views/Shared/Components/{View Component Name}/{View Name}
  • /Pages/Shared/Components/{View Component Name}/{View Name}
  • /Areas/{Area Name}/Views/Shared/Components/{View Component Name}/{View Name}

Cesta hledání se vztahuje na projekty používající kontrolery a zobrazení a Razor stránky.

Výchozí název zobrazení komponenty zobrazení je Default, což znamená, že soubory zobrazení budou obvykle pojmenovány Default.cshtml. Při vytváření výsledku komponenty zobrazení nebo při volání View metody lze zadat jiný název zobrazení.

Doporučujeme pojmenovat soubor Default.cshtml zobrazení a použít cestu Views/Shared/Components/{View Component Name}/{View Name} . Součást zobrazení použitá PriorityList v této ukázce se používá Views/Shared/Components/PriorityList/Default.cshtml pro zobrazení komponenty zobrazení.

Přizpůsobení cesty hledání zobrazení

Pokud chcete upravit cestu hledání zobrazení, upravte Razorkolekci ViewLocationFormats . Pokud například chcete vyhledat zobrazení v cestě /Components/{View Component Name}/{View Name}, přidejte do kolekce novou položku:

using Microsoft.EntityFrameworkCore;
using ViewComponentSample.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews()
    .AddRazorOptions(options =>
    {
        options.ViewLocationFormats.Add("/{0}.cshtml");
    });

builder.Services.AddDbContext<ToDoContext>(options =>
        options.UseInMemoryDatabase("db"));

var app = builder.Build();

// Remaining code removed for brevity.

V předchozím kódu zástupný symbol {0} představuje cestu Components/{View Component Name}/{View Name}.

Vyvolání komponenty zobrazení

Chcete-li použít součást zobrazení, zavolejte v zobrazení následující:

@await Component.InvokeAsync("Name of view component",
                             {Anonymous Type Containing Parameters})

Parametry jsou předány metodě InvokeAsync . Komponenta PriorityList zobrazení vyvinutá v článku se vyvolá ze Views/ToDo/Index.cshtml souboru zobrazení. V následujícím kódu InvokeAsync je volána metoda se dvěma parametry:

</table>

<div>
    Maximum Priority: @ViewData["maxPriority"] <br />
    Is Complete:  @ViewData["isDone"]
    @await Component.InvokeAsync("PriorityList",
                     new { 
                         maxPriority =  ViewData["maxPriority"],
                         isDone = ViewData["isDone"]  }
                     )
</div>

Vyvolání komponenty zobrazení jako pomocné rutiny značek

Komponentu zobrazení lze vyvolat jako pomocnou rutinu značky:

<div>
       Maxium Priority: @ViewData["maxPriority"] <br />
       Is Complete:  @ViewData["isDone"]
    @{
        int maxPriority = Convert.ToInt32(ViewData["maxPriority"]);
        bool isDone = Convert.ToBoolean(ViewData["isDone"]);
    }
    <vc:priority-list max-priority=maxPriority is-done=isDone>
    </vc:priority-list>
</div>

Pascal-cased třídy a parametry metody pro pomocné rutiny značek jsou přeloženy do jejich kebab case. Pomocná rutina značky k vyvolání komponenty zobrazení používá <vc></vc> element. Součást zobrazení je určena následujícím způsobem:

<vc:[view-component-name]
  parameter1="parameter1 value"
  parameter2="parameter2 value">
</vc:[view-component-name]>

Chcete-li použít součást zobrazení jako pomocník značky, zaregistrujte sestavení obsahující součást zobrazení pomocí direktivy @addTagHelper . Pokud je součást zobrazení v sestavení volána MyWebApp, přidejte do souboru následující direktivu _ViewImports.cshtml :

@addTagHelper *, MyWebApp

Součást zobrazení lze zaregistrovat jako pomocnou rutinu značky do libovolného souboru, který odkazuje na komponentu zobrazení. Další informace o registraci pomocných rutin značek najdete v tématu Správa oboru pomocných rutin značek.

Metoda použitá InvokeAsync v tomto kurzu:

@await Component.InvokeAsync("PriorityList",
                 new { 
                     maxPriority =  ViewData["maxPriority"],
                     isDone = ViewData["isDone"]  }
                 )

V předchozím kódu se komponenta PriorityList zobrazení stane priority-list. Parametry komponenty zobrazení se předávají jako atributy v případě kebabu.

Vyvolání komponenty zobrazení přímo z kontroleru

Komponenty zobrazení jsou obvykle vyvolány ze zobrazení, ale lze je vyvolat přímo z metody kontroleru. I když komponenty zobrazení nedefinují koncové body, jako jsou kontrolery, akce kontroleru, která vrací obsah nějakého ViewComponentResult obsahu, je možné implementovat.

V následujícím příkladu se komponenta zobrazení volá přímo z kontroleru:

public IActionResult IndexVC(int maxPriority = 2, bool isDone = false)
{
    return ViewComponent("PriorityList",
        new { 
           maxPriority = maxPriority,
           isDone = isDone
        });
}

Vytvoření komponenty základního zobrazení

Stáhněte, sestavte a otestujte počáteční kód. Jedná se o základní projekt s kontrolerem ToDo , který zobrazuje seznam položek úkolů .

List of ToDos

Aktualizace kontroleru tak, aby předával prioritu a stav dokončení

Aktualizujte metodu Index tak, aby používala parametry stavu priority a dokončení:

using Microsoft.AspNetCore.Mvc;
using ViewComponentSample.Models;

namespace ViewComponentSample.Controllers;
public class ToDoController : Controller
{
    private readonly ToDoContext _ToDoContext;

    public ToDoController(ToDoContext context)
    {
        _ToDoContext = context;
        _ToDoContext.Database.EnsureCreated();
    }

    public IActionResult Index(int maxPriority = 2, bool isDone = false)
    {
        var model = _ToDoContext!.ToDo!.ToList();
        ViewData["maxPriority"] = maxPriority;
        ViewData["isDone"] = isDone;
        return View(model);
    }

Přidání třídy ViewComponent

Přidejte třídu ViewComponent do ViewComponents/PriorityListViewComponent.cs:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ViewComponentSample.Models;

namespace ViewComponentSample.ViewComponents;

public class PriorityListViewComponent : ViewComponent
{
    private readonly ToDoContext db;

    public PriorityListViewComponent(ToDoContext context) => db = context;

    public async Task<IViewComponentResult> InvokeAsync(
                                            int maxPriority, bool isDone)
    {
        var items = await GetItemsAsync(maxPriority, isDone);
        return View(items);
    }

    private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
    {
        return db!.ToDo!.Where(x => x.IsDone == isDone &&
                             x.Priority <= maxPriority).ToListAsync();
    }
}

Poznámky k kódu:

  • Třídy komponent zobrazení mohou být obsaženy v libovolné složce v projektu.

  • Vzhledem k tomu, že název třídy PriorityListViewComponent končí příponou ViewComponent, modul runtime používá řetězec PriorityList při odkazování na komponentu třídy ze zobrazení.

  • Atribut [ViewComponent] může změnit název použitý pro odkaz na součást zobrazení. Třída může mít například název XYZ s následujícím [ViewComponent] atributem:

    [ViewComponent(Name = "PriorityList")]
       public class XYZ : ViewComponent
    
  • Atribut [ViewComponent] v předchozím kódu říká selektoru komponenty zobrazení, který má použít:

    • Název PriorityList při hledání zobrazení přidružených ke komponentě
    • Řetězec PriorityList při odkazování na komponentu třídy ze zobrazení.
  • Komponenta používá injektáž závislostí k zpřístupnění kontextu dat.

  • InvokeAsync zveřejňuje metodu, kterou lze volat ze zobrazení, a může mít libovolný počet argumentů.

  • Metoda InvokeAsync vrátí sadu ToDo položek, které vyhovují parametrůmisDone.maxPriority

Vytvoření zobrazení komponenty Razor zobrazení

  • Vytvořte složku Views/Shared/Components. Tato složka musí mít název Součásti.

  • Vytvořte složku Views/Shared/Components/PriorityList. Tento název složky musí odpovídat názvu třídy komponenty zobrazení nebo názvu třídy minus příponu. ViewComponent Pokud se atribut použije, název třídy by se měl shodovat s označením atributu.

  • Vytvoření Views/Shared/Components/PriorityList/Default.cshtmlRazor zobrazení:

    @model IEnumerable<ViewComponentSample.Models.TodoItem>
    
    <h3>Priority Items</h3>
    <ul>
        @foreach (var todo in Model)
        {
            <li>@todo.Name</li>
        }
    </ul>
    

    Zobrazení Razor obsahuje seznam TodoItem a zobrazuje je. Pokud metoda komponenty InvokeAsync view nepředá název zobrazení, použije se výchozí pro název zobrazení podle konvence. Pokud chcete přepsat výchozí styl konkrétního kontroleru, přidejte zobrazení do složky zobrazení specifické pro kontroler (například Views/ToDo/Components/PriorityList/Default.cshtml).

    Pokud je součást zobrazení specifická pro řadič, lze ji přidat do složky specifické pro kontroler. Například Views/ToDo/Components/PriorityList/Default.cshtml je specifický pro kontroler.

  • div Přidejte do dolní části Views/ToDo/index.cshtml souboru volání obsahující volání komponenty seznamu priorit:

    </table>
    
    <div>
        Maximum Priority: @ViewData["maxPriority"] <br />
        Is Complete:  @ViewData["isDone"]
        @await Component.InvokeAsync("PriorityList",
                         new { 
                             maxPriority =  ViewData["maxPriority"],
                             isDone = ViewData["isDone"]  }
                         )
    </div>
    

@await Component.InvokeAsync Revize zobrazuje syntaxi pro komponenty zobrazení volání. Prvním argumentem je název komponenty, kterou chceme vyvolat nebo volat. Další parametry se předají komponentě. InvokeAsync může mít libovolný počet argumentů.

Otestujete aplikaci. Následující obrázek ukazuje seznam úkolů a prioritní položky:

todo list and priority items

Komponentu zobrazení lze volat přímo z kontroleru:

public IActionResult IndexVC(int maxPriority = 2, bool isDone = false)
{
    return ViewComponent("PriorityList",
        new { 
           maxPriority = maxPriority,
           isDone = isDone
        });
}

priority items from IndexVC action

Zadání názvu komponenty zobrazení

Komponenta komplexního zobrazení může za určitých podmínek potřebovat zadat jiné než výchozí zobrazení. Následující kód ukazuje, jak určit zobrazení PVC z InvokeAsync metody. Aktualizujte metodu InvokeAsyncPriorityListViewComponent ve třídě.

public async Task<IViewComponentResult> InvokeAsync(
                                           int maxPriority, bool isDone)
{
    string MyView = "Default";
    // If asking for all completed tasks, render with the "PVC" view.
    if (maxPriority > 3 && isDone == true)
    {
        MyView = "PVC";
    }
    var items = await GetItemsAsync(maxPriority, isDone);
    return View(MyView, items);
}

Views/Shared/Components/PriorityList/Default.cshtml Zkopírujte soubor do zobrazení s názvem Views/Shared/Components/PriorityList/PVC.cshtml. Přidejte nadpis, který označuje, že se používá zobrazení PVC.

@model IEnumerable<ViewComponentSample.Models.TodoItem>

<h2> PVC Named Priority Component View</h2>
<h4>@ViewBag.PriorityMessage</h4>
<ul>
    @foreach (var todo in Model)
    {
        <li>@todo.Name</li>
    }
</ul>

Spusťte aplikaci a ověřte zobrazení PVC.

Priority View Component

Pokud zobrazení PVC není vykreslené, ověřte, zda je volána součást zobrazení s prioritou 4 nebo vyšší.

Prozkoumání cesty zobrazení

  • Změňte parametr priority na tři nebo méně, takže se nevrátí zobrazení priority.

  • Dočasně přejmenujte Views/ToDo/Components/PriorityList/Default.cshtml na 1Default.cshtml.

  • Otestujte aplikaci, dojde k následující chybě:

    An unhandled exception occurred while processing the request.
    InvalidOperationException: The view 'Components/PriorityList/Default' wasn't found. The following locations were searched:
    /Views/ToDo/Components/PriorityList/Default.cshtml
    /Views/Shared/Components/PriorityList/Default.cshtml
    
  • Zkopírujte soubor Views/ToDo/Components/PriorityList/1Default.cshtml do složky Views/Shared/Components/PriorityList/Default.cshtml.

  • Přidejte do zobrazení komponenty zobrazení Sdílené toDo nějaké revize, které indikují, že zobrazení je ze sdílené složky.

  • Otestujte zobrazení sdílené komponenty.

ToDo output with Shared component view

Vyhněte se pevně zakódovaným řetězcům

Pro zabezpečení doby kompilace nahraďte pevně zakódovaný název komponenty zobrazení názvem třídy. Aktualizujte soubor PriorityListViewComponent.cs tak, aby nepoužít příponu ViewComponent:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ViewComponentSample.Models;

namespace ViewComponentSample.ViewComponents;

public class PriorityList : ViewComponent
{
    private readonly ToDoContext db;

    public PriorityList(ToDoContext context)
    {
        db = context;
    }

    public async Task<IViewComponentResult> InvokeAsync(
                                               int maxPriority, bool isDone)
    {
        var items = await GetItemsAsync(maxPriority, isDone);
        return View(items);
    }

    private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
    {
        return db!.ToDo!.Where(x => x.IsDone == isDone &&
                             x.Priority <= maxPriority).ToListAsync();
    }
}

Soubor zobrazení :

</table>

<div>
    Testing nameof(PriorityList) <br />

    Maxium Priority: @ViewData["maxPriority"] <br />
    Is Complete:  @ViewData["isDone"]
    @await Component.InvokeAsync(nameof(PriorityList),
                     new { 
                         maxPriority =  ViewData["maxPriority"],
                         isDone = ViewData["isDone"]  }
                     )
</div>

Přetížení Component.InvokeAsync metody, která přebírá typ CLR, používá typeof operátor:

</table>

<div>
    Testing typeof(PriorityList) <br />

    Maxium Priority: @ViewData["maxPriority"] <br />
    Is Complete:  @ViewData["isDone"]
    @await Component.InvokeAsync(typeof(PriorityList),
                     new { 
                         maxPriority =  ViewData["maxPriority"],
                         isDone = ViewData["isDone"]  }
                     )
</div>

Provádění synchronní práce

Architektura zpracovává vyvolání synchronní Invoke metody, pokud není vyžadována asynchronní práce. Následující metoda vytvoří synchronní Invoke komponentu zobrazení:

using Microsoft.AspNetCore.Mvc;
using ViewComponentSample.Models;

namespace ViewComponentSample.ViewComponents
{
    public class PriorityListSync : ViewComponent
    {
        private readonly ToDoContext db;

        public PriorityListSync(ToDoContext context)
        {
            db = context;
        }

        public IViewComponentResult Invoke(int maxPriority, bool isDone)
        {
 
            var x = db!.ToDo!.Where(x => x.IsDone == isDone &&
                                  x.Priority <= maxPriority).ToList();
            return View(x);
        }
    }
}

Soubor komponenty Razor zobrazení:

<div>
    Testing nameof(PriorityList) <br />

    Maxium Priority: @ViewData["maxPriority"] <br />
    Is Complete:  @ViewData["isDone"]
    @await Component.InvokeAsync(nameof(PriorityListSync),
                     new { 
                         maxPriority =  ViewData["maxPriority"],
                         isDone = ViewData["isDone"]  }
                     )
</div>

Komponenta Razor zobrazení se vyvolá v souboru (například Views/Home/Index.cshtml) pomocí jednoho z následujících přístupů:

Pokud chcete použít IViewComponentHelper přístup, zavolejte Component.InvokeAsync:

@await Component.InvokeAsync(nameof(PriorityList),
                             new { maxPriority = 4, isDone = true })

Chcete-li použít pomocné rutiny značek, zaregistrujte sestavení obsahující součást Zobrazení pomocí direktivy @addTagHelper (součást zobrazení je v sestavení s názvem MyWebApp):

@addTagHelper *, MyWebApp

V souboru značek použijte pomocné rutiny značky Razor komponenty zobrazení:

<vc:priority-list max-priority="999" is-done="false">
</vc:priority-list>

Podpis PriorityList.Invoke metody je synchronní, ale Razor najde a volá metodu v Component.InvokeAsync souboru značek.

Další prostředky

Komponenty zobrazení

Komponenty zobrazení se podobají částečným zobrazením, ale jsou mnohem výkonnější. Komponenty zobrazení nepoužívají vazbu modelu, závisí na datech předaných při volání komponenty zobrazení. Tento článek byl napsán pomocí kontrolerů a zobrazení, ale komponenty zobrazení fungují se stránkamiRazor.

Součást zobrazení:

  • Vykreslí blok dat místo celé odpovědi.
  • Zahrnuje stejné výhody oddělení a testovatelnosti, které byly nalezeny mezi kontrolerem a zobrazením.
  • Může mít parametry a obchodní logiku.
  • Obvykle je vyvolána ze stránky rozložení.

Součásti zobrazení jsou určené kdekoli opakovaně použitelná logika vykreslování, která je pro částečné zobrazení příliš složitá, například:

  • Dynamické navigační nabídky
  • Označování cloudu, kde se dotazuje databáze
  • Panel Přihlášení
  • Nákupní košík
  • Nedávno publikované články
  • Obsah bočního panelu na blogu
  • Přihlašovací panel, který by se vykresloval na každé stránce a zobrazoval odkazy pro odhlášení nebo přihlášení v závislosti na stavu přihlášení uživatele

Součást zobrazení se skládá ze dvou částí:

  • Třída, obvykle odvozená z ViewComponent
  • Výsledek, který vrátí, obvykle zobrazení.

Podobně jako kontrolery může být komponenta zobrazení POCO, ale většina vývojářů využívá metody a vlastnosti, které jsou k dispozici odvozením z ViewComponent.

Při zvažování, jestli komponenty zobrazení splňují specifikace aplikace, zvažte místo toho použití Razor komponent. Razor komponenty také kombinují značky s kódem jazyka C#, aby se vytvořily opakovaně použitelné jednotky uživatelského rozhraní. Razor komponenty jsou navržené pro produktivitu vývojářů při poskytování logiky a složení uživatelského rozhraní na straně klienta. Další informace najdete v tématu ASP.NET základní Razor komponenty. Informace o tom, jak začlenit Razor komponenty do aplikace MVC nebo Razor Pages, najdete v tématu Prerender a integrace komponent ASP.NET CoreRazor.

Vytvoření komponenty zobrazení

Tato část obsahuje požadavky vysoké úrovně pro vytvoření komponenty zobrazení. Později v článku podrobně prozkoumáme jednotlivé kroky a vytvoříme součást zobrazení.

Třída komponenty view

Třídu komponenty zobrazení lze vytvořit některou z následujících možností:

Podobně jako kontrolery musí být součásti zobrazení veřejné, vnořené a ne abstraktní třídy. Název komponenty zobrazení je název třídy s odebranou příponou ViewComponent . Lze ho Name také explicitně zadat pomocí vlastnosti.

Třída komponenty view:

  • Podporuje injektáž závislostí konstruktoru .
  • Neúčastní se životního cyklu kontroleru, proto se filtry nedají použít v komponentě zobrazení.

Chcete-li zabránit třídě, která má příponu nerozlišující ViewComponent malá a velká písmena, aby byla považována za součást zobrazení, ozdobte třídu atributem [NonViewComponent] :

using Microsoft.AspNetCore.Mvc;

[NonViewComponent]
public class ReviewComponent
{
    public string Status(string name) => JobStatus.GetCurrentStatus(name);
}

Zobrazení metod komponent

Komponenta zobrazení definuje svou logiku v:

  • InvokeAsync metoda, která vrací Task<IViewComponentResult>.
  • Invoke synchronní metoda, která vrací hodnotu IViewComponentResult.

Parametry pocházejí přímo z vyvolání komponenty zobrazení, nikoli z vazby modelu. Komponenta zobrazení nikdy přímo nezpracuje požadavek. Komponenta zobrazení obvykle inicializuje model a předává ho do zobrazení voláním View metody. V souhrnu zobrazte metody komponent:

  • Definujte metodu InvokeAsyncTask<IViewComponentResult>, která vrací nebo synchronní Invoke metodu, která vrací .IViewComponentResult
  • Obvykle inicializuje model a předá ho do zobrazení voláním ViewComponent.View metoda.
  • Parametry pocházejí z volající metody, nikoli HTTP. Neexistuje žádná vazba modelu.
  • Není dostupný přímo jako koncový bod HTTP. Obvykle se vyvolávají v zobrazení. Komponenta zobrazení nikdy nezpracuje požadavek.
  • Jsou přetíženy u podpisu místo jakýchkoli podrobností z aktuálního požadavku HTTP.

Zobrazit cestu hledání

Modul runtime hledá zobrazení v následujících cestách:

  • /Views/{Controller Name}/Components/{View Component Name}/{View Name}
  • /Views/Shared/Components/{View Component Name}/{View Name}
  • /Pages/Shared/Components/{View Component Name}/{View Name}
  • /Areas/{Area Name}/Views/Shared/Components/{View Component Name}/{View Name}

Cesta hledání se vztahuje na projekty používající kontrolery a zobrazení a Razor stránky.

Výchozí název zobrazení komponenty zobrazení je Default, což znamená, že soubory zobrazení budou obvykle pojmenovány Default.cshtml. Při vytváření výsledku komponenty zobrazení nebo při volání View metody lze zadat jiný název zobrazení.

Doporučujeme pojmenovat soubor Default.cshtml zobrazení a použít cestu Views/Shared/Components/{View Component Name}/{View Name} . Součást zobrazení použitá PriorityList v této ukázce se používá Views/Shared/Components/PriorityList/Default.cshtml pro zobrazení komponenty zobrazení.

Přizpůsobení cesty hledání zobrazení

Pokud chcete upravit cestu hledání zobrazení, upravte Razorkolekci ViewLocationFormats . Pokud například chcete vyhledat zobrazení v cestě /Components/{View Component Name}/{View Name}, přidejte do kolekce novou položku:

using Microsoft.EntityFrameworkCore;
using ViewComponentSample.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews()
    .AddRazorOptions(options =>
    {
        options.ViewLocationFormats.Add("/{0}.cshtml");
    });

builder.Services.AddDbContext<ToDoContext>(options =>
        options.UseInMemoryDatabase("db"));

var app = builder.Build();

// Remaining code removed for brevity.

V předchozím kódu zástupný symbol {0} představuje cestu Components/{View Component Name}/{View Name}.

Vyvolání komponenty zobrazení

Chcete-li použít součást zobrazení, zavolejte v zobrazení následující:

@await Component.InvokeAsync("Name of view component",
                             {Anonymous Type Containing Parameters})

Parametry jsou předány metodě InvokeAsync . Komponenta PriorityList zobrazení vyvinutá v článku se vyvolá ze Views/ToDo/Index.cshtml souboru zobrazení. V následujícím kódu InvokeAsync je volána metoda se dvěma parametry:

</table>

<div>
    Maximum Priority: @ViewData["maxPriority"] <br />
    Is Complete:  @ViewData["isDone"]
    @await Component.InvokeAsync("PriorityList",
                     new { 
                         maxPriority =  ViewData["maxPriority"],
                         isDone = ViewData["isDone"]  }
                     )
</div>

Vyvolání komponenty zobrazení jako pomocné rutiny značek

Komponentu zobrazení lze vyvolat jako pomocnou rutinu značky:

<div>
       Maxium Priority: @ViewData["maxPriority"] <br />
       Is Complete:  @ViewData["isDone"]
    @{
        int maxPriority = Convert.ToInt32(ViewData["maxPriority"]);
        bool isDone = Convert.ToBoolean(ViewData["isDone"]);
    }
    <vc:priority-list max-priority=maxPriority is-done=isDone>
    </vc:priority-list>
</div>

Pascal-cased třídy a parametry metody pro pomocné rutiny značek jsou přeloženy do jejich kebab case. Pomocná rutina značky k vyvolání komponenty zobrazení používá <vc></vc> element. Součást zobrazení je určena následujícím způsobem:

<vc:[view-component-name]
  parameter1="parameter1 value"
  parameter2="parameter2 value">
</vc:[view-component-name]>

Chcete-li použít součást zobrazení jako pomocník značky, zaregistrujte sestavení obsahující součást zobrazení pomocí direktivy @addTagHelper . Pokud je součást zobrazení v sestavení volána MyWebApp, přidejte do souboru následující direktivu _ViewImports.cshtml :

@addTagHelper *, MyWebApp

Součást zobrazení lze zaregistrovat jako pomocnou rutinu značky do libovolného souboru, který odkazuje na komponentu zobrazení. Další informace o registraci pomocných rutin značek najdete v tématu Správa oboru pomocných rutin značek.

Metoda použitá InvokeAsync v tomto kurzu:

@await Component.InvokeAsync("PriorityList",
                 new { 
                     maxPriority =  ViewData["maxPriority"],
                     isDone = ViewData["isDone"]  }
                 )

V předchozím kódu se komponenta PriorityList zobrazení stane priority-list. Parametry komponenty zobrazení se předávají jako atributy v případě kebabu.

Vyvolání komponenty zobrazení přímo z kontroleru

Komponenty zobrazení jsou obvykle vyvolány ze zobrazení, ale lze je vyvolat přímo z metody kontroleru. I když komponenty zobrazení nedefinují koncové body, jako jsou kontrolery, akce kontroleru, která vrací obsah nějakého ViewComponentResult obsahu, je možné implementovat.

V následujícím příkladu se komponenta zobrazení volá přímo z kontroleru:

public IActionResult IndexVC(int maxPriority = 2, bool isDone = false)
{
    return ViewComponent("PriorityList",
        new { 
           maxPriority = maxPriority,
           isDone = isDone
        });
}

Vytvoření komponenty základního zobrazení

Stáhněte, sestavte a otestujte počáteční kód. Jedná se o základní projekt s kontrolerem ToDo , který zobrazuje seznam položek úkolů .

List of ToDos

Aktualizace kontroleru tak, aby předával prioritu a stav dokončení

Aktualizujte metodu Index tak, aby používala parametry stavu priority a dokončení:

using Microsoft.AspNetCore.Mvc;
using ViewComponentSample.Models;

namespace ViewComponentSample.Controllers;
public class ToDoController : Controller
{
    private readonly ToDoContext _ToDoContext;

    public ToDoController(ToDoContext context)
    {
        _ToDoContext = context;
        _ToDoContext.Database.EnsureCreated();
    }

    public IActionResult Index(int maxPriority = 2, bool isDone = false)
    {
        var model = _ToDoContext!.ToDo!.ToList();
        ViewData["maxPriority"] = maxPriority;
        ViewData["isDone"] = isDone;
        return View(model);
    }

Přidání třídy ViewComponent

Přidejte třídu ViewComponent do ViewComponents/PriorityListViewComponent.cs:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ViewComponentSample.Models;

namespace ViewComponentSample.ViewComponents;

public class PriorityListViewComponent : ViewComponent
{
    private readonly ToDoContext db;

    public PriorityListViewComponent(ToDoContext context) => db = context;

    public async Task<IViewComponentResult> InvokeAsync(
                                            int maxPriority, bool isDone)
    {
        var items = await GetItemsAsync(maxPriority, isDone);
        return View(items);
    }

    private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
    {
        return db!.ToDo!.Where(x => x.IsDone == isDone &&
                             x.Priority <= maxPriority).ToListAsync();
    }
}

Poznámky k kódu:

  • Třídy komponent zobrazení mohou být obsaženy v libovolné složce v projektu.

  • Vzhledem k tomu, že název třídy PriorityListViewComponent končí příponou ViewComponent, modul runtime používá řetězec PriorityList při odkazování na komponentu třídy ze zobrazení.

  • Atribut [ViewComponent] může změnit název použitý pro odkaz na součást zobrazení. Třída může mít například název XYZ s následujícím [ViewComponent] atributem:

    [ViewComponent(Name = "PriorityList")]
       public class XYZ : ViewComponent
    
  • Atribut [ViewComponent] v předchozím kódu říká selektoru komponenty zobrazení, který má použít:

    • Název PriorityList při hledání zobrazení přidružených ke komponentě
    • Řetězec PriorityList při odkazování na komponentu třídy ze zobrazení.
  • Komponenta používá injektáž závislostí k zpřístupnění kontextu dat.

  • InvokeAsync zveřejňuje metodu, kterou lze volat ze zobrazení, a může mít libovolný počet argumentů.

  • Metoda InvokeAsync vrátí sadu ToDo položek, které vyhovují parametrůmisDone.maxPriority

Vytvoření zobrazení komponenty Razor zobrazení

  • Vytvořte složku Views/Shared/Components. Tato složka musí mít název Součásti.

  • Vytvořte složku Views/Shared/Components/PriorityList. Tento název složky musí odpovídat názvu třídy komponenty zobrazení nebo názvu třídy minus příponu. ViewComponent Pokud se atribut použije, název třídy by se měl shodovat s označením atributu.

  • Vytvoření Views/Shared/Components/PriorityList/Default.cshtmlRazor zobrazení:

    @model IEnumerable<ViewComponentSample.Models.TodoItem>
    
    <h3>Priority Items</h3>
    <ul>
        @foreach (var todo in Model)
        {
            <li>@todo.Name</li>
        }
    </ul>
    

    Zobrazení Razor obsahuje seznam TodoItem a zobrazuje je. Pokud metoda komponenty InvokeAsync view nepředá název zobrazení, použije se výchozí pro název zobrazení podle konvence. Pokud chcete přepsat výchozí styl konkrétního kontroleru, přidejte zobrazení do složky zobrazení specifické pro kontroler (například Views/ToDo/Components/PriorityList/Default.cshtml).

    Pokud je součást zobrazení specifická pro řadič, lze ji přidat do složky specifické pro kontroler. Například Views/ToDo/Components/PriorityList/Default.cshtml je specifický pro kontroler.

  • div Přidejte do dolní části Views/ToDo/index.cshtml souboru volání obsahující volání komponenty seznamu priorit:

    </table>
    
    <div>
        Maximum Priority: @ViewData["maxPriority"] <br />
        Is Complete:  @ViewData["isDone"]
        @await Component.InvokeAsync("PriorityList",
                         new { 
                             maxPriority =  ViewData["maxPriority"],
                             isDone = ViewData["isDone"]  }
                         )
    </div>
    

@await Component.InvokeAsync Revize zobrazuje syntaxi pro komponenty zobrazení volání. Prvním argumentem je název komponenty, kterou chceme vyvolat nebo volat. Další parametry se předají komponentě. InvokeAsync může mít libovolný počet argumentů.

Otestujete aplikaci. Následující obrázek ukazuje seznam úkolů a prioritní položky:

todo list and priority items

Komponentu zobrazení lze volat přímo z kontroleru:

public IActionResult IndexVC(int maxPriority = 2, bool isDone = false)
{
    return ViewComponent("PriorityList",
        new { 
           maxPriority = maxPriority,
           isDone = isDone
        });
}

priority items from IndexVC action

Zadání názvu komponenty zobrazení

Komponenta komplexního zobrazení může za určitých podmínek potřebovat zadat jiné než výchozí zobrazení. Následující kód ukazuje, jak určit zobrazení PVC z InvokeAsync metody. Aktualizujte metodu InvokeAsyncPriorityListViewComponent ve třídě.

public async Task<IViewComponentResult> InvokeAsync(
                                           int maxPriority, bool isDone)
{
    string MyView = "Default";
    // If asking for all completed tasks, render with the "PVC" view.
    if (maxPriority > 3 && isDone == true)
    {
        MyView = "PVC";
    }
    var items = await GetItemsAsync(maxPriority, isDone);
    return View(MyView, items);
}

Views/Shared/Components/PriorityList/Default.cshtml Zkopírujte soubor do zobrazení s názvem Views/Shared/Components/PriorityList/PVC.cshtml. Přidejte nadpis, který označuje, že se používá zobrazení PVC.

@model IEnumerable<ViewComponentSample.Models.TodoItem>

<h2> PVC Named Priority Component View</h2>
<h4>@ViewBag.PriorityMessage</h4>
<ul>
    @foreach (var todo in Model)
    {
        <li>@todo.Name</li>
    }
</ul>

Spusťte aplikaci a ověřte zobrazení PVC.

Priority View Component

Pokud zobrazení PVC není vykreslené, ověřte, zda je volána součást zobrazení s prioritou 4 nebo vyšší.

Prozkoumání cesty zobrazení

  • Změňte parametr priority na tři nebo méně, takže se nevrátí zobrazení priority.

  • Dočasně přejmenujte Views/ToDo/Components/PriorityList/Default.cshtml na 1Default.cshtml.

  • Otestujte aplikaci, dojde k následující chybě:

    An unhandled exception occurred while processing the request.
    InvalidOperationException: The view 'Components/PriorityList/Default' wasn't found. The following locations were searched:
    /Views/ToDo/Components/PriorityList/Default.cshtml
    /Views/Shared/Components/PriorityList/Default.cshtml
    
  • Zkopírujte soubor Views/ToDo/Components/PriorityList/1Default.cshtml do složky Views/Shared/Components/PriorityList/Default.cshtml.

  • Přidejte do zobrazení komponenty zobrazení Sdílené toDo nějaké revize, které indikují, že zobrazení je ze sdílené složky.

  • Otestujte zobrazení sdílené komponenty.

ToDo output with Shared component view

Vyhněte se pevně zakódovaným řetězcům

Pro zabezpečení doby kompilace nahraďte pevně zakódovaný název komponenty zobrazení názvem třídy. Aktualizujte soubor PriorityListViewComponent.cs tak, aby nepoužít příponu ViewComponent:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ViewComponentSample.Models;

namespace ViewComponentSample.ViewComponents;

public class PriorityList : ViewComponent
{
    private readonly ToDoContext db;

    public PriorityList(ToDoContext context)
    {
        db = context;
    }

    public async Task<IViewComponentResult> InvokeAsync(
                                               int maxPriority, bool isDone)
    {
        var items = await GetItemsAsync(maxPriority, isDone);
        return View(items);
    }

    private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
    {
        return db!.ToDo!.Where(x => x.IsDone == isDone &&
                             x.Priority <= maxPriority).ToListAsync();
    }
}

Soubor zobrazení :

</table>

<div>
    Testing nameof(PriorityList) <br />

    Maxium Priority: @ViewData["maxPriority"] <br />
    Is Complete:  @ViewData["isDone"]
    @await Component.InvokeAsync(nameof(PriorityList),
                     new { 
                         maxPriority =  ViewData["maxPriority"],
                         isDone = ViewData["isDone"]  }
                     )
</div>

Přetížení Component.InvokeAsync metody, která přebírá typ CLR, používá typeof operátor:

</table>

<div>
    Testing typeof(PriorityList) <br />

    Maxium Priority: @ViewData["maxPriority"] <br />
    Is Complete:  @ViewData["isDone"]
    @await Component.InvokeAsync(typeof(PriorityList),
                     new { 
                         maxPriority =  ViewData["maxPriority"],
                         isDone = ViewData["isDone"]  }
                     )
</div>

Provádění synchronní práce

Architektura zpracovává vyvolání synchronní Invoke metody, pokud není vyžadována asynchronní práce. Následující metoda vytvoří synchronní Invoke komponentu zobrazení:

using Microsoft.AspNetCore.Mvc;
using ViewComponentSample.Models;

namespace ViewComponentSample.ViewComponents
{
    public class PriorityListSync : ViewComponent
    {
        private readonly ToDoContext db;

        public PriorityListSync(ToDoContext context)
        {
            db = context;
        }

        public IViewComponentResult Invoke(int maxPriority, bool isDone)
        {
 
            var x = db!.ToDo!.Where(x => x.IsDone == isDone &&
                                  x.Priority <= maxPriority).ToList();
            return View(x);
        }
    }
}

Soubor komponenty Razor zobrazení:

<div>
    Testing nameof(PriorityList) <br />

    Maxium Priority: @ViewData["maxPriority"] <br />
    Is Complete:  @ViewData["isDone"]
    @await Component.InvokeAsync(nameof(PriorityListSync),
                     new { 
                         maxPriority =  ViewData["maxPriority"],
                         isDone = ViewData["isDone"]  }
                     )
</div>

Komponenta Razor zobrazení se vyvolá v souboru (například Views/Home/Index.cshtml) pomocí jednoho z následujících přístupů:

Pokud chcete použít IViewComponentHelper přístup, zavolejte Component.InvokeAsync:

@await Component.InvokeAsync(nameof(PriorityList),
                             new { maxPriority = 4, isDone = true })

Chcete-li použít pomocné rutiny značek, zaregistrujte sestavení obsahující součást Zobrazení pomocí direktivy @addTagHelper (součást zobrazení je v sestavení s názvem MyWebApp):

@addTagHelper *, MyWebApp

V souboru značek použijte pomocné rutiny značky Razor komponenty zobrazení:

<vc:priority-list max-priority="999" is-done="false">
</vc:priority-list>

Podpis PriorityList.Invoke metody je synchronní, ale Razor najde a volá metodu v Component.InvokeAsync souboru značek.

Další prostředky

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Komponenty zobrazení

Komponenty zobrazení se podobají částečným zobrazením, ale jsou mnohem výkonnější. Komponenty zobrazení nepoužívají vazbu modelu a závisí pouze na datech zadaných při jejich volání. Tento článek byl napsán pomocí kontrolerů a zobrazení, ale komponenty zobrazení pracují také se stránkami Razor .

Součást zobrazení:

  • Vykreslí blok dat místo celé odpovědi.
  • Zahrnuje stejné výhody oddělení a testovatelnosti, které byly nalezeny mezi kontrolerem a zobrazením.
  • Může mít parametry a obchodní logiku.
  • Obvykle je vyvolána ze stránky rozložení.

Součásti zobrazení jsou určené všude, kde máte opakovaně použitelnou logiku vykreslování, která je pro částečné zobrazení příliš složitá, například:

  • Dynamické navigační nabídky
  • Označování cloudu (kde se dotazuje databáze)
  • Panel přihlášení
  • Nákupní košík
  • Nedávno publikované články
  • Obsah bočního panelu na typickém blogu
  • Přihlašovací panel, který by se vykresloval na každé stránce a zobrazoval odkazy pro odhlášení nebo přihlášení v závislosti na stavu přihlášení uživatele

Součást zobrazení se skládá ze dvou částí: třídy (obvykle odvozené) ViewComponenta výsledku, který vrací (obvykle zobrazení). Podobně jako kontrolery může být komponenta zobrazení POCO, ale většina vývojářů využívá metody a vlastnosti, které jsou k dispozici odvozením z ViewComponent.

Při zvažování, jestli komponenty zobrazení splňují specifikace aplikace, zvažte místo toho použití Razor komponent. Razor komponenty také kombinují značky s kódem jazyka C#, aby se vytvořily opakovaně použitelné jednotky uživatelského rozhraní. Razor komponenty jsou navržené pro produktivitu vývojářů při poskytování logiky a složení uživatelského rozhraní na straně klienta. Další informace najdete v tématu ASP.NET základní Razor komponenty. Informace o tom, jak začlenit Razor komponenty do aplikace MVC nebo Razor Pages, najdete v tématu Prerender a integrace komponent ASP.NET CoreRazor.

Vytvoření komponenty zobrazení

Tato část obsahuje požadavky vysoké úrovně pro vytvoření komponenty zobrazení. Později v článku podrobně prozkoumáme jednotlivé kroky a vytvoříme součást zobrazení.

Třída komponenty view

Třídu komponenty zobrazení lze vytvořit některou z následujících možností:

  • Odvození z funkce ViewComponent
  • Dekódování třídy atributem [ViewComponent] nebo odvození od třídy atributem [ViewComponent]
  • Vytvoření třídy, kde název končí příponou ViewComponent

Podobně jako kontrolery musí být součásti zobrazení veřejné, vnořené a ne abstraktní třídy. Název komponenty zobrazení je název třídy s odebranou příponou ViewComponent. Lze ho ViewComponentAttribute.Name také explicitně zadat pomocí vlastnosti.

Třída komponenty view:

  • Plně podporuje injektáž závislostí konstruktoru .
  • Neúčastní se životního cyklu kontroleru, což znamená, že v komponentě zobrazení nemůžete použít filtry .

Chcete-li zastavit třídu, která má nerozlišující velká a malá písmena přípony ViewComponent , aby byla považována za součást zobrazení, ozdobte třídu atributem [NonViewComponent] :

[NonViewComponent]
public class ReviewComponent
{
    // ...

Zobrazení metod komponent

Komponenta zobrazení definuje svou logiku InvokeAsync v metodě, která vrací Task<IViewComponentResult> synchronní metodu IViewComponentResultnebo v synchronní Invoke metodě, která vrací . Parametry pocházejí přímo z vyvolání komponenty zobrazení, nikoli z vazby modelu. Komponenta zobrazení nikdy přímo nezpracuje požadavek. Komponenta zobrazení obvykle inicializuje model a předává ho do zobrazení voláním View metody. V souhrnu zobrazte metody komponent:

  • Definujte metodu InvokeAsyncTask<IViewComponentResult>, která vrací nebo synchronní Invoke metodu, která vrací .IViewComponentResult
  • Obvykle inicializuje model a předá ho do zobrazení voláním ViewComponentView metody.
  • Parametry pocházejí z volající metody, nikoli HTTP. Neexistuje žádná vazba modelu.
  • Nejsou dostupné přímo jako koncový bod HTTP. Volají se z vašeho kódu (obvykle v zobrazení). Komponenta zobrazení nikdy nezpracuje požadavek.
  • Jsou přetíženy u podpisu místo jakýchkoli podrobností z aktuálního požadavku HTTP.

Zobrazit cestu hledání

Modul runtime hledá zobrazení v následujících cestách:

  • /Views/{Controller Name}/Components/{View Component Name}/{View Name}
  • /Views/Shared/Components/{View Component Name}/{View Name}
  • /Pages/Shared/Components/{View Component Name}/{View Name}
  • /Areas/{Area Name}/Views/Shared/Components/{View Component Name}/{View Name}

Cesta hledání se vztahuje na projekty používající kontrolery a zobrazení a Razor stránky.

Výchozí název zobrazení komponenty zobrazení je Výchozí, což znamená, že soubor zobrazení bude obvykle pojmenován Default.cshtml. Při vytváření výsledku komponenty zobrazení nebo při volání View metody můžete zadat jiný název zobrazení.

Doporučujeme pojmenovat soubor Default.cshtml zobrazení a použít cestu Zobrazení/ Sdílené součásti/{Název součásti zobrazení}/{Název zobrazení}.} Součást zobrazení použitá PriorityList v této ukázce se používá Views/Shared/Components/PriorityList/Default.cshtml pro zobrazení komponenty zobrazení.

Přizpůsobení cesty hledání zobrazení

Pokud chcete upravit cestu hledání zobrazení, upravte Razorkolekci ViewLocationFormats . Pokud chcete například vyhledat zobrazení v cestě /Components/{View Component Name}/{View Name}, přidejte do kolekce novou položku:

services.AddMvc()
    .AddRazorOptions(options =>
    {
        options.ViewLocationFormats.Add("/{0}.cshtml");
    })
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

Zástupný symbol "{0}" v předchozím kódu představuje cestu Components/{View Component Name}/{View Name}.

Vyvolání komponenty zobrazení

Chcete-li použít součást zobrazení, zavolejte v zobrazení následující:

@await Component.InvokeAsync("Name of view component", {Anonymous Type Containing Parameters})

Parametry budou předány metodě InvokeAsync . Komponenta PriorityList zobrazení vyvinutá v článku se vyvolá ze Views/ToDo/Index.cshtml souboru zobrazení. V následujícím příkladu InvokeAsync je volána metoda se dvěma parametry:

@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })

Vyvolání komponenty zobrazení jako pomocné rutiny značek

Pro ASP.NET Core 1.1 a vyšší můžete vyvolat součást zobrazení jako pomocnou rutinu značek:

<vc:priority-list max-priority="2" is-done="false">
</vc:priority-list>

Pascal-cased třídy a parametry metody pro pomocné rutiny značek jsou přeloženy do jejich kebab case. Pomocná rutina značky k vyvolání komponenty zobrazení používá <vc></vc> element. Součást zobrazení je určena následujícím způsobem:

<vc:[view-component-name]
  parameter1="parameter1 value"
  parameter2="parameter2 value">
</vc:[view-component-name]>

Chcete-li použít součást zobrazení jako pomocník značky, zaregistrujte sestavení obsahující součást zobrazení pomocí direktivy @addTagHelper . Pokud je součást zobrazení v sestavení volána MyWebApp, přidejte do souboru následující direktivu _ViewImports.cshtml :

@addTagHelper *, MyWebApp

Součást zobrazení můžete zaregistrovat jako pomocnou rutinu značky do libovolného souboru, který odkazuje na komponentu zobrazení. Další informace o registraci pomocných rutin značek najdete v tématu Správa oboru pomocných rutin značek.

Metoda použitá InvokeAsync v tomto kurzu:

@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })

V pomocném kódu značek:

<vc:priority-list max-priority="2" is-done="false">
</vc:priority-list>

V ukázce výše se komponenta PriorityList zobrazení stane priority-list. Parametry komponenty zobrazení se předávají jako atributy v případě kebabu.

Vyvolání komponenty zobrazení přímo z kontroleru

Součásti zobrazení jsou obvykle vyvolány ze zobrazení, ale můžete je vyvolat přímo z metody kontroleru. I když součásti zobrazení nedefinují koncové body, jako jsou kontrolery, můžete snadno implementovat akci kontroleru, která vrací obsah ViewComponentResult.

V tomto příkladu se komponenta zobrazení volá přímo z kontroleru:

public IActionResult IndexVC()
{
    return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}

Návod: Vytvoření komponenty jednoduchého zobrazení

Stáhněte, sestavte a otestujte počáteční kód. Jedná se o jednoduchý projekt s kontrolerem ToDo , který zobrazuje seznam položek ToDo .

List of ToDos

Přidání třídy ViewComponent

Vytvořte složku ViewComponents a přidejte následující PriorityListViewComponent třídu:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ViewComponentSample.Models;

namespace ViewComponentSample.ViewComponents
{
    public class PriorityListViewComponent : ViewComponent
    {
        private readonly ToDoContext db;

        public PriorityListViewComponent(ToDoContext context)
        {
            db = context;
        }

        public async Task<IViewComponentResult> InvokeAsync(
        int maxPriority, bool isDone)
        {
            var items = await GetItemsAsync(maxPriority, isDone);
            return View(items);
        }
        private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
        {
            return db.ToDo.Where(x => x.IsDone == isDone &&
                                 x.Priority <= maxPriority).ToListAsync();
        }
    }
}

Poznámky k kódu:

  • Třídy komponent zobrazení mohou být obsaženy v libovolné složce v projektu.

  • Vzhledem k tomu, že název třídy PriorityListViewComponent končí příponou ViewComponent, modul runtime používá řetězec PriorityList při odkazování na komponentu třídy ze zobrazení.

  • Atribut [ViewComponent] může změnit název použitý pro odkaz na součást zobrazení. Třída mohla být například pojmenována XYZ atributem ViewComponent :

    [ViewComponent(Name = "PriorityList")]
       public class XYZ : ViewComponent
    
  • Atribut [ViewComponent] v předchozím kódu říká selektoru komponenty zobrazení, který má použít:

    • Název PriorityList při hledání zobrazení přidružených ke komponentě
    • Řetězec PriorityList při odkazování na komponentu třídy ze zobrazení.
  • Komponenta používá injektáž závislostí k zpřístupnění kontextu dat.

  • InvokeAsync zveřejňuje metodu, kterou lze volat ze zobrazení, a může mít libovolný počet argumentů.

  • Metoda InvokeAsync vrátí sadu ToDo položek, které vyhovují parametrůmisDone.maxPriority

Vytvoření zobrazení komponenty Razor zobrazení

  • Vytvořte složku Views/Shared/Components. Tato složka musí mít název Components.

  • Vytvořte složku Views/Shared/Components/PriorityList. Tento název složky se musí shodovat s názvem třídy komponenty zobrazení nebo názvem třídy minus příponu (pokud jsme postupovali podle konvence a použili jsme příponu ViewComponent v názvu třídy). Pokud jste atribut použili ViewComponent , název třídy by se měl shodovat s označením atributu.

  • Vytvoření Views/Shared/Components/PriorityList/Default.cshtmlRazor zobrazení:

    @model IEnumerable<ViewComponentSample.Models.TodoItem>
    
    <h3>Priority Items</h3>
    <ul>
        @foreach (var todo in Model)
        {
            <li>@todo.Name</li>
        }
    </ul>
    

    Zobrazení Razor obsahuje seznam TodoItem a zobrazuje je. Pokud metoda komponenty InvokeAsync view nepředá název zobrazení (jako v naší ukázce), použije se výchozí hodnota pro název zobrazení podle konvence. Později v kurzu vám ukážu, jak předat název zobrazení. Pokud chcete přepsat výchozí styl konkrétního kontroleru, přidejte zobrazení do složky zobrazení specifické pro kontroler (například Views/ToDo/Components/PriorityList/Default.cshtml).

    Pokud je součást zobrazení specifická pro kontroler, můžete ji přidat do složky specifické pro kontroler (Views/ToDo/Components/PriorityList/Default.cshtml).

  • div Přidejte do dolní části Views/ToDo/index.cshtml souboru volání obsahující volání komponenty seznamu priorit:

    </table>
    <div>
        @await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
    </div>
    

@await Component.InvokeAsync Revize zobrazuje syntaxi pro komponenty zobrazení volání. Prvním argumentem je název komponenty, kterou chceme vyvolat nebo volat. Další parametry se předají komponentě. InvokeAsync může mít libovolný počet argumentů.

Otestujete aplikaci. Následující obrázek ukazuje seznam úkolů a prioritní položky:

todo list and priority items

Komponentu zobrazení můžete také volat přímo z kontroleru:

public IActionResult IndexVC()
{
    return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}

priority items from IndexVC action

Zadání názvu zobrazení

Komponenta komplexního zobrazení může za určitých podmínek potřebovat zadat jiné než výchozí zobrazení. Následující kód ukazuje, jak určit zobrazení PVC z InvokeAsync metody. Aktualizujte metodu InvokeAsyncPriorityListViewComponent ve třídě.

public async Task<IViewComponentResult> InvokeAsync(
    int maxPriority, bool isDone)
{
    string MyView = "Default";
    // If asking for all completed tasks, render with the "PVC" view.
    if (maxPriority > 3 && isDone == true)
    {
        MyView = "PVC";
    }
    var items = await GetItemsAsync(maxPriority, isDone);
    return View(MyView, items);
}

Views/Shared/Components/PriorityList/Default.cshtml Zkopírujte soubor do zobrazení s názvem Views/Shared/Components/PriorityList/PVC.cshtml. Přidejte nadpis, který označuje, že se používá zobrazení PVC.

@model IEnumerable<ViewComponentSample.Models.TodoItem>

<h2> PVC Named Priority Component View</h2>
<h4>@ViewBag.PriorityMessage</h4>
<ul>
    @foreach (var todo in Model)
    {
        <li>@todo.Name</li>
    }
</ul>

Aktualizace Views/ToDo/Index.cshtml:

@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })

Spusťte aplikaci a ověřte zobrazení PVC.

Priority View Component

Pokud se zobrazení PVC nevykreslí, ověřte, že voláte součást zobrazení s prioritou 4 nebo vyšší.

Prozkoumání cesty zobrazení

  • Změňte parametr priority na tři nebo méně, takže se nevrátí zobrazení priority.

  • Dočasně přejmenujte Views/ToDo/Components/PriorityList/Default.cshtml na 1Default.cshtml.

  • Otestujte aplikaci, zobrazí se následující chyba:

    An unhandled exception occurred while processing the request.
    InvalidOperationException: The view 'Components/PriorityList/Default' wasn't found. The following locations were searched:
    /Views/ToDo/Components/PriorityList/Default.cshtml
    /Views/Shared/Components/PriorityList/Default.cshtml
    EnsureSuccessful
    
  • Zkopírujte soubor Views/ToDo/Components/PriorityList/1Default.cshtml do složky Views/Shared/Components/PriorityList/Default.cshtml.

  • Přidejte do zobrazení komponenty zobrazení Sdílené toDo nějaké revize, které indikují, že zobrazení je ze sdílené složky.

  • Otestujte zobrazení sdílené komponenty.

ToDo output with Shared component view

Vyhněte se pevně zakódovaným řetězcům

Pokud chcete bezpečnost času kompilace, můžete nahradit pevně zakódovaný název komponenty zobrazení názvem třídy. Vytvořte komponentu zobrazení bez přípony ViewComponent:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ViewComponentSample.Models;

namespace ViewComponentSample.ViewComponents
{
    public class PriorityList : ViewComponent
    {
        private readonly ToDoContext db;

        public PriorityList(ToDoContext context)
        {
            db = context;
        }

        public async Task<IViewComponentResult> InvokeAsync(
        int maxPriority, bool isDone)
        {
            var items = await GetItemsAsync(maxPriority, isDone);
            return View(items);
        }
        private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
        {
            return db.ToDo.Where(x => x.IsDone == isDone &&
                                 x.Priority <= maxPriority).ToListAsync();
        }
    }
}

using Přidejte do Razor souboru zobrazení příkaz a použijte nameof operátor:

@using ViewComponentSample.Models
@using ViewComponentSample.ViewComponents
@model IEnumerable<TodoItem>

    <h2>ToDo nameof</h2>
    <!-- Markup removed for brevity.  -->

    <div>

        @*
            Note: 
            To use the below line, you need to #define no_suffix in ViewComponents/PriorityList.cs or it won't compile.
            By doing so it will cause a problem to index as there will be multiple viewcomponents 
            with the same name after the compiler removes the suffix "ViewComponent"
        *@

        @*@await Component.InvokeAsync(nameof(PriorityList), new { maxPriority = 4, isDone = true })*@
    </div>

Můžete použít přetížení Component.InvokeAsync metody, která přebírá typ CLR. Nezapomeňte v tomto případě použít typeof operátor:

@using ViewComponentSample.Models
@using ViewComponentSample.ViewComponents
@model IEnumerable<TodoItem>

<h2>ToDo typeof</h2>
<!-- Markup removed for brevity.  -->

<div>
    @await Component.InvokeAsync(typeof(PriorityListViewComponent), new { maxPriority = 4, isDone = true })
</div>

Provádění synchronní práce

Architektura zpracovává vyvolání synchronní Invoke metody, pokud nepotřebujete provádět asynchronní práci. Následující metoda vytvoří synchronní Invoke komponentu zobrazení:

public class PriorityList : ViewComponent
{
    public IViewComponentResult Invoke(int maxPriority, bool isDone)
    {
        var items = new List<string> { $"maxPriority: {maxPriority}", $"isDone: {isDone}" };
        return View(items);
    }
}

Soubor komponenty Razor view obsahuje seznam řetězců předaných Invoke metodě (Views/Home/Components/PriorityList/Default.cshtml):

@model List<string>

<h3>Priority Items</h3>
<ul>
    @foreach (var item in Model)
    {
        <li>@item</li>
    }
</ul>

Komponenta Razor zobrazení se vyvolá v souboru (například Views/Home/Index.cshtml) pomocí jednoho z následujících přístupů:

Pokud chcete použít IViewComponentHelper přístup, zavolejte Component.InvokeAsync:

@await Component.InvokeAsync(nameof(PriorityList), new { maxPriority = 4, isDone = true })

Chcete-li použít pomocné rutiny značek, zaregistrujte sestavení obsahující součást Zobrazení pomocí direktivy @addTagHelper (součást zobrazení je v sestavení s názvem MyWebApp):

@addTagHelper *, MyWebApp

V souboru značek použijte pomocné rutiny značky Razor komponenty zobrazení:

<vc:priority-list max-priority="999" is-done="false">
</vc:priority-list>

Podpis PriorityList.Invoke metody je synchronní, ale Razor najde a volá metodu v Component.InvokeAsync souboru značek.

Všechny parametry komponenty zobrazení jsou povinné.

Každý parametr v komponentě zobrazení je povinný atribut. Podívejte se na tento problém na GitHubu. Pokud některý parametr vynecháte:

  • Podpis InvokeAsync metody se neshoduje, proto se metoda nespustí.
  • Funkce ViewComponent nevykreslí žádné revize.
  • Nebudou vyvolán žádné chyby.

Další prostředky