Megosztás a következőn keresztül:


Összetevők megtekintése a ASP.NET Core-ban

Készítette: Rick Anderson

Összetevők megtekintése

A nézetösszetevők hasonlóak a részleges nézetekhez, de sokkal hatékonyabbak. A nézetösszetevők nem használnak modellkötést, a nézetösszetevő meghívása során átadott adatoktól függenek. Ez a cikk vezérlők és nézetek használatával készült, de a nézetösszetevők együttműködnek a Pages szolgáltatássalRazor.

Nézetösszetevő:

  • Egy adattömb megjelenítése teljes válasz helyett.
  • Ugyanolyan felelősségek elkülönítését és tesztelhetőségi előnyöket kínál, mint a vezérlő és a nézet között.
  • Paraméterekkel és üzleti logikával rendelkezhet.
  • Általában egy elrendezési oldalról hívjuk meg.

A nézetösszetevők olyan helyzetekben jönnek szóba, ahol újrafelhasználható renderelési logikára van szükség, amely túl összetett egy részleges nézethez, például:

  • Dinamikus navigációs menük
  • Címkefelhő, ahol az adatbázist lekérdezi
  • Bejelentkezési panel
  • Bevásárlókocsi
  • Nemrég közzétett cikkek
  • Oldalsáv tartalma egy blogon
  • Egy bejelentkezési panel, amely minden oldalon megjelenik, és megjeleníti a kijelentkezni vagy bejelentkezni kívánt hivatkozásokat a felhasználó bejelentkezési állapotától függően

A nézetösszetevő két részből áll:

  • Az osztály, amely általában a ViewComponent
  • Az eredmény, amit visszaad, általában egy nézet.

A vezérlőkhöz hasonlóan a nézetösszetevők is lehetnek POCO-k, de a fejlesztők többsége kihasználja az elérhető ViewComponentmódszereket és tulajdonságokat.

Ha azt mérlegeli, hogy a megjelenítési összetevők megfelelnek-e az alkalmazás specifikációinak, érdemes megfontolni a összetevők alkalmazását helyettük. Razor az összetevők a korrektúra és a C#-kód kombinálásával újrahasználható felhasználói felületi egységeket hoznak létre. Razor az összetevőket úgy tervezték, hogy az ügyféloldali felhasználói felület logikájának és összetételének biztosításakor a fejlesztői hatékonyságot szolgálják. További információ: ASP.NET Core-összetevőkRazor. Az összetevők MVC- vagy Pages-alkalmazásokba való beépítésére Razor vonatkozó információkért lásd: Razor.Razor

Nézetösszetevő létrehozása

Ez a szakasz a nézetösszetevő létrehozásának magas szintű követelményeit tartalmazza. A cikk későbbi részében részletesen megvizsgáljuk az egyes lépéseket, és létrehozunk egy nézetösszetevőt.

A nézet összetevőosztálya

A nézetösszetevő-osztályt az alábbiak bármelyike hozhatja létre:

  • Származtatás: ViewComponent
  • Az osztály díszítése az [ViewComponent] attribútummal, vagy egy [ViewComponent] attribútummal rendelkező osztályból való származtatással
  • Olyan osztály létrehozása, amelyben a név az utótaggal végződik ViewComponent

A vezérlőkhöz hasonlóan a nézetösszetevőknek nyilvánosnak, nem beágyazottnak és nem absztrakt osztályoknak kell lenniük. A nézetösszetevő neve az osztály neve, és az ViewComponent utótag el lett távolítva. A Name tulajdonság explicit módon is megadható.

Nézetösszetevő-osztály:

Ha meg szeretné akadályozni, hogy egy kis- és nagybetűre nem érzékeny utótaggal rendelkező ViewComponent osztályt nézetösszetevőként kezeljen, díszítse az osztályt az [NonViewComponent] attribútummal:

using Microsoft.AspNetCore.Mvc;

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

Összetevők metódusának megtekintése

A nézetösszetevő a logikáját az alábbiakban határozza meg:

  • InvokeAsync metódus, amely visszatér Task<IViewComponentResult>.
  • Invoke szinkron metódus, amely egy IViewComponentResult.

A paraméterek közvetlenül a nézetösszetevő meghívásából származnak, nem a modellkötésből. A nézetösszetevők soha nem kezelik közvetlenül a kéréseket. A nézet komponens általában inicializál egy modellt, és a View metódus meghívásával adja át azt egy nézetnek. Összefoglalva, tekintse meg az összetevők metódusát:

  • Definiáljon egy InvokeAsync metódust, amely egy Task<IViewComponentResult>-ot ad vissza, vagy egy szinkron Invoke metódust, amely egy IViewComponentResult-t ad vissza.
  • Általában inicializál egy modellt, és a ViewComponent.View metódus meghívásával továbbítja azt egy nézetnek.
  • A paraméterek a hívó metódusból származnak, nem a HTTP-ből. Nincs modellkötés.
  • Nem érhető el közvetlenül HTTP-végpontként. Ezeket általában egy nézetben hívják meg. A nézetösszetevők soha nem kezelik a kéréseket.
  • A túlterhelés az aláíráson van, nem pedig az aktuális HTTP-kérés részletein.

Keresési útvonal megtekintése

A futtatókörnyezet a következő útvonalakon keresi a nézetet:

  • /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}

A keresési útvonal a vezérlőket és nézeteket, valamint Razor oldalakat használó projektekre vonatkozik.

A nézetösszetevő alapértelmezett nézetneve az Default, ami azt jelenti, hogy a nézetfájlok neve általában el lesz nevezve Default.cshtml. A nézetösszetevő eredményének létrehozásakor vagy a View metódus meghívásakor más nézetnév adható meg.

Javasoljuk, hogy nevezze el a nézetfájlt Default.cshtml , és használja a Nézetek/Megosztott/Összetevők/{Összetevő neve}/{Nézet neve} elérési utat. Az ebben a mintában használt PriorityList nézetösszetevő Views/Shared/Components/PriorityList/Default.cshtml használ a megjelenítéshez.

A nézet keresési útvonalának testreszabása

A nézet keresési útvonalának testreszabásához módosítsa a Razor gyűjtemény ViewLocationFormats-jét. Ha például az elérési úton /Components/{View Component Name}/{View Name}lévő nézeteket szeretné keresni, adjon hozzá egy új elemet a gyűjteményhez:

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.

Az előző kódban a helyőrző {0} az elérési utat Components/{View Component Name}/{View Name}jelöli.

Nézetösszetevő meghívása

A nézetösszetevő használatához hívja meg a következőt egy nézeten belül:

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

A paramétereket a rendszer átadja a InvokeAsync metódusnak. A PriorityList cikkben kifejlesztett nézetösszetevő meghívása a Views/ToDo/Index.cshtml nézetfájlból történik. A következő kódban a InvokeAsync metódus két paraméterrel van meghívva:

</table>

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

Nézetösszetevő meghívása Tag Helperként

A nézetösszetevő Tag Helperként meghívható:

<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>

A Tag Helpers pascal-cased osztály- és metódusparaméterei a kebab-esetükre lesznek lefordítva. A nézetösszetevő meghívásához használt címkesegítő az <vc></vc> elemet használja. A nézetösszetevő a következőképpen van megadva:

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

Ha egy nézetösszetevőt címkesegítőként szeretne használni, regisztrálja a nézetösszetevőt tartalmazó szerelvényt az @addTagHelper irányelv használatával. Ha a nézetösszetevő egy úgynevezett MyWebAppszerelvényben található, adja hozzá a következő irányelvet a _ViewImports.cshtml fájlhoz:

@addTagHelper *, MyWebApp

A nézetösszetevők címkesegítőként regisztrálhatók a nézetösszetevőre hivatkozó bármely fájlra. A címkesegítők regisztrálásáról további információt a Címkesegítő hatókör kezelése című témakörben talál.

Az InvokeAsync oktatóanyagban használt módszer:

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

Az előző jelölőnyelvben a PriorityList nézetösszetevővé válik, amely priority-list lesz. A nézetösszetevő paramétereit a rendszer attribútumként adja át a kebab-esetben.

Nézetösszetevő meghívása közvetlenül egy vezérlőből

A nézetösszetevők általában egy nézetből hívhatók meg, de közvetlenül egy vezérlőmetódusból hívhatók meg. Bár a nézetösszetevők nem határoznak meg olyan végpontokat, mint a vezérlők, egy vezérlőművelet implementálható, amely egy adott ViewComponentResult tartalom tartalmát adja vissza.

A következő példában a nézetösszetevőt közvetlenül a vezérlőből hívjuk meg:

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

Alapszintű nézetösszetevő létrehozása

Töltse le, készítse el és tesztelje a kezdőkódot. Ez egy alapszintű projekt egy ToDo vezérlővel, amely megjeleníti a ToDo-elemek listáját.

ToDos-lista

A vezérlő frissítése a prioritás és a befejezés állapotának átadása érdekében

Frissítse a metódust a Index prioritási és befejezési állapot paramétereinek használatára:

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);
    }

ViewComponent-osztály hozzáadása

ViewComponent-osztály hozzáadása a következőhöz 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();
    }
}

Megjegyzések a kódhoz:

  • Az összetevőosztályok megtekintése a projekt bármely mappájában megtalálható.

  • Mivel a PriorityListViewComponent osztálynév a ViewComponent utótaggal végződik, a futtatókörnyezet a sztringet PriorityList használja, amikor egy nézetből hivatkozik az osztály összetevőjére.

  • Az [ViewComponent] attribútum megváltoztathatja a nézetösszetevőre való hivatkozáshoz használt nevet. Például az osztály lehetett volna a következő attribútummal megnevezve: XYZ[ViewComponent].

    [ViewComponent(Name = "PriorityList")]
       public class XYZ : ViewComponent
    
  • Az [ViewComponent] előző kódban szereplő attribútum a nézetösszetevő-választót a következőre utasítja:

    • Amikor a PriorityList nevet használja az összetevőhöz kapcsolódó nézetek keresésére
    • A "PriorityList" sztring, amikor az osztályösszetevőre hivatkozik egy nézetből.
  • Az összetevő függőséginjektálás használatával teszi elérhetővé az adatkörnyezetet.

  • InvokeAsync egy nézetből meghívható metódust tesz elérhetővé, és tetszőleges számú argumentumot vehet igénybe.

  • A InvokeAsync metódus visszaadja a ToDo halmazt, amely elemek megfelelnek a isDone és maxPriority paramétereknek.

A nézetösszetevő Razor nézet létrehozása

  • Hozza létre a Nézetek/Megosztott/Összetevők mappát. Ennek a mappának Componentskell lennie.

  • Hozza létre a Views/Shared/Components/PriorityList mappát. Ennek a mappanévnek meg kell egyeznie a nézetösszetevő-osztály nevével, vagy az osztály nevével, az utótag nélkül. Ha az ViewComponent attribútumot használja, az osztály nevének meg kell egyeznie az attribútum megjelölésével.

  • Views/Shared/Components/PriorityList/Default.cshtml Razor Nézet létrehozása:

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

    A Razor nézet felsorolja TodoItem és megjeleníti őket. Ha a nézetösszetevő InvokeAsync metódus nem felel meg a nézet nevének, a nézet neve konvenciók szerint az Alapértelmezett értéket használja. Egy adott vezérlő alapértelmezett stílusának felülbírálásához adjon hozzá egy nézetet a vezérlőspecifikus nézetmappához (például Nézetek/ToDo/Components/PriorityList/Default.cshtml).

    Ha a nézetösszetevő vezérlőspecifikus, hozzáadható a vezérlőspecifikus mappához. Például Views/ToDo/Components/PriorityList/Default.cshtml vezérlőspecifikus.

  • Adjon hozzá egy div hívást a prioritáslista összetevőhöz a Views/ToDo/index.cshtml fájl aljára:

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

A korrektúra @await Component.InvokeAsync a nézetösszetevők hívásának szintaxisát jeleníti meg. Az első argumentum a meghívni vagy hívni kívánt összetevő neve. A rendszer további paramétereket ad át az összetevőnek. InvokeAsync tetszőleges számú argumentumot vehet fel.

Tesztelje az alkalmazást. Az alábbi képen a ToDo lista és a prioritási elemek láthatók:

teendőlista és prioritáselemek

A nézetösszetevő közvetlenül a vezérlőből hívható meg:

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

prioritási elemek az IndexVC műveletből

Nézetösszetevő nevének megadása

Előfordulhat, hogy egy összetett nézetösszetevőnek bizonyos feltételek mellett nem alapértelmezett nézetet kell megadnia. Az alábbi kód bemutatja, hogyan adhatja meg a "PVC" nézetet a InvokeAsync metódusból. Frissítse a metódust InvokeAsync az PriorityListViewComponent osztályban.

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);
}

Másolja a Views/Shared/Components/PriorityList/Default.cshtml fájlt egy nevesített Views/Shared/Components/PriorityList/PVC.cshtmlnézetbe. Adjon hozzá egy címsort, amely jelzi, hogy a PVC-nézet használatban van.

@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>

Futtassa az alkalmazást, és ellenőrizze a PVC nézetet.

Prioritás nézet komponens

Ha a PVC nézet nem jelenik meg, ellenőrizze, hogy a nézetösszetevő 4 vagy annál magasabb prioritással van-e meghívva.

A nézet elérési útjának vizsgálata

  • Módosítsa a prioritási paramétert három vagy kevesebbre, hogy a prioritási nézet ne legyen visszaadva.

  • Ideiglenesen nevezze át a Views/ToDo/Components/PriorityList/Default.cshtml következőre: 1Default.cshtml.

  • Tesztelje az alkalmazást, a következő hiba történik:

    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
    
  • Másolja át a következőt: Views/ToDo/Components/PriorityList/1Default.cshtml ide: Views/Shared/Components/PriorityList/Default.cshtml.

  • Adjon hozzá néhány korrektúrát a Megosztott toDo nézet összetevő nézetéhez, hogy jelezze, hogy a nézet a Megosztott mappából származik.

  • Tesztelje a Megosztott összetevő nézetet.

ToDo kimenet megosztott összetevő nézettel

A kódolt sztringek elkerülése

A fordítási idő biztonsága érdekében cserélje le a hard-coded view összetevő nevét az osztálynévre. Frissítse a PriorityListViewComponent.cs fájlt úgy, hogy ne használja a "ViewComponent" utótagot:

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();
    }
}

A nézetfájl:

</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>

A Component.InvokeAsync metódus túlterhelése, amely egy CLR típust vesz át, a typeof operátort használja.

</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>

Szinkron munka végrehajtása

A keretrendszer kezeli a szinkron Invoke metódus meghívását, ha nincs szükség aszinkron munkára. A következő metódus létrehoz egy szinkron Invoke nézetösszetevőt:

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);
        }
    }
}

A nézetösszetevő fájlja Razor :

<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>

A nézetösszetevőt egy Razor fájlban (például Views/Home/Index.cshtml) hívja meg a rendszer az alábbi módszerek egyikével:

A IViewComponentHelper megközelítés használatához hívja meg a Component.InvokeAsync-t.

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

A Címkesegítő használatához regisztrálja a Nézet összetevőt tartalmazó szerelvényt az @addTagHelper irányelv használatával (a nézetösszetevő egy úgynevezett MyWebAppszerelvényben található):

@addTagHelper *, MyWebApp

A Razor jelölőfájlban használja a View Component Tag Helper-t.

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

A PriorityList.Invoke metódus aláírása szinkron, de a Razor megkeresi és meghívja a metódust a Component.InvokeAsync jelölőfájlban.

További erőforrások

Összetevők megtekintése

A nézetösszetevők hasonlóak a részleges nézetekhez, de sokkal hatékonyabbak. A nézetösszetevők nem használnak modellkötést, a nézetösszetevő meghívása során átadott adatoktól függenek. Ez a cikk vezérlők és nézetek használatával készült, de a nézetösszetevők együttműködnek a Pages szolgáltatássalRazor.

Nézetösszetevő:

  • Egy adattömb megjelenítése teljes válasz helyett.
  • Ugyanolyan felelősségek elkülönítését és tesztelhetőségi előnyöket kínál, mint a vezérlő és a nézet között.
  • Paraméterekkel és üzleti logikával rendelkezhet.
  • Általában egy elrendezési oldalról hívjuk meg.

A nézetösszetevők olyan helyzetekben jönnek szóba, ahol újrafelhasználható renderelési logikára van szükség, amely túl összetett egy részleges nézethez, például:

  • Dinamikus navigációs menük
  • Címkefelhő, ahol az adatbázist lekérdezi
  • Bejelentkezési panel
  • Bevásárlókocsi
  • Nemrég közzétett cikkek
  • Oldalsáv tartalma egy blogon
  • Egy bejelentkezési panel, amely minden oldalon megjelenik, és megjeleníti a kijelentkezni vagy bejelentkezni kívánt hivatkozásokat a felhasználó bejelentkezési állapotától függően

A nézetösszetevő két részből áll:

  • Az osztály, amely általában a ViewComponent
  • Az eredmény, amit visszaad, általában egy nézet.

A vezérlőkhöz hasonlóan a nézetösszetevők is lehetnek POCO-k, de a fejlesztők többsége kihasználja az elérhető ViewComponentmódszereket és tulajdonságokat.

Ha azt mérlegeli, hogy a megjelenítési összetevők megfelelnek-e az alkalmazás specifikációinak, érdemes megfontolni a összetevők alkalmazását helyettük. Razor az összetevők a korrektúra és a C#-kód kombinálásával újrahasználható felhasználói felületi egységeket hoznak létre. Razor az összetevőket úgy tervezték, hogy az ügyféloldali felhasználói felület logikájának és összetételének biztosításakor a fejlesztői hatékonyságot szolgálják. További információ: ASP.NET Core-összetevőkRazor. Az összetevők MVC- vagy Pages-alkalmazásokba való beépítésére Razor vonatkozó információkért lásd: Razor.Razor

Nézetösszetevő létrehozása

Ez a szakasz a nézetösszetevő létrehozásának magas szintű követelményeit tartalmazza. A cikk későbbi részében részletesen megvizsgáljuk az egyes lépéseket, és létrehozunk egy nézetösszetevőt.

A nézet összetevőosztálya

A nézetösszetevő-osztályt az alábbiak bármelyike hozhatja létre:

  • Származtatás: ViewComponent
  • Az osztály díszítése az [ViewComponent] attribútummal, vagy egy [ViewComponent] attribútummal rendelkező osztályból való származtatással
  • Olyan osztály létrehozása, amelyben a név az utótaggal végződik ViewComponent

A vezérlőkhöz hasonlóan a nézetösszetevőknek nyilvánosnak, nem beágyazottnak és nem absztrakt osztályoknak kell lenniük. A nézetösszetevő neve az osztály neve, és az ViewComponent utótag el lett távolítva. A Name tulajdonság explicit módon is megadható.

Nézetösszetevő-osztály:

Ha meg szeretné akadályozni, hogy egy kis- és nagybetűre nem érzékeny utótaggal rendelkező ViewComponent osztályt nézetösszetevőként kezeljen, díszítse az osztályt az [NonViewComponent] attribútummal:

using Microsoft.AspNetCore.Mvc;

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

Összetevők metódusának megtekintése

A nézetösszetevő a logikáját az alábbiakban határozza meg:

  • InvokeAsync metódus, amely visszatér Task<IViewComponentResult>.
  • Invoke szinkron metódus, amely egy IViewComponentResult.

A paraméterek közvetlenül a nézetösszetevő meghívásából származnak, nem a modellkötésből. A nézetösszetevők soha nem kezelik közvetlenül a kéréseket. A nézet komponens általában inicializál egy modellt, és a View metódus meghívásával adja át azt egy nézetnek. Összefoglalva, tekintse meg az összetevők metódusát:

  • Definiáljon egy InvokeAsync metódust, amely egy Task<IViewComponentResult>-ot ad vissza, vagy egy szinkron Invoke metódust, amely egy IViewComponentResult-t ad vissza.
  • Általában inicializál egy modellt, és a ViewComponent.View metódus meghívásával továbbítja azt egy nézetnek.
  • A paraméterek a hívó metódusból származnak, nem a HTTP-ből. Nincs modellkötés.
  • Nem érhető el közvetlenül HTTP-végpontként. Ezeket általában egy nézetben hívják meg. A nézetösszetevők soha nem kezelik a kéréseket.
  • A túlterhelés az aláíráson van, nem pedig az aktuális HTTP-kérés részletein.

Keresési útvonal megtekintése

A futtatókörnyezet a következő útvonalakon keresi a nézetet:

  • /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}

A keresési útvonal a vezérlőket és nézeteket, valamint Razor oldalakat használó projektekre vonatkozik.

A nézetösszetevő alapértelmezett nézetneve az Default, ami azt jelenti, hogy a nézetfájlok neve általában el lesz nevezve Default.cshtml. A nézetösszetevő eredményének létrehozásakor vagy a View metódus meghívásakor más nézetnév adható meg.

Javasoljuk, hogy nevezze el a nézetfájlt Default.cshtml , és használja a Nézetek/Megosztott/Összetevők/{Összetevő neve}/{Nézet neve} elérési utat. Az ebben a mintában használt PriorityList nézetösszetevő Views/Shared/Components/PriorityList/Default.cshtml használ a megjelenítéshez.

A nézet keresési útvonalának testreszabása

A nézet keresési útvonalának testreszabásához módosítsa a Razor gyűjtemény ViewLocationFormats-jét. Ha például az elérési úton /Components/{View Component Name}/{View Name}lévő nézeteket szeretné keresni, adjon hozzá egy új elemet a gyűjteményhez:

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.

Az előző kódban a helyőrző {0} az elérési utat Components/{View Component Name}/{View Name}jelöli.

Nézetösszetevő meghívása

A nézetösszetevő használatához hívja meg a következőt egy nézeten belül:

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

A paramétereket a rendszer átadja a InvokeAsync metódusnak. A PriorityList cikkben kifejlesztett nézetösszetevő meghívása a Views/ToDo/Index.cshtml nézetfájlból történik. A következő kódban a InvokeAsync metódus két paraméterrel van meghívva:

</table>

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

Nézetösszetevő meghívása Tag Helperként

A nézetösszetevő Tag Helperként meghívható:

<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>

A Tag Helpers pascal-cased osztály- és metódusparaméterei a kebab-esetükre lesznek lefordítva. A nézetösszetevő meghívásához használt címkesegítő az <vc></vc> elemet használja. A nézetösszetevő a következőképpen van megadva:

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

Ha egy nézetösszetevőt címkesegítőként szeretne használni, regisztrálja a nézetösszetevőt tartalmazó szerelvényt az @addTagHelper irányelv használatával. Ha a nézetösszetevő egy úgynevezett MyWebAppszerelvényben található, adja hozzá a következő irányelvet a _ViewImports.cshtml fájlhoz:

@addTagHelper *, MyWebApp

A nézetösszetevők címkesegítőként regisztrálhatók a nézetösszetevőre hivatkozó bármely fájlra. A címkesegítők regisztrálásáról további információt a Címkesegítő hatókör kezelése című témakörben talál.

Az InvokeAsync oktatóanyagban használt módszer:

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

Az előző jelölőnyelvben a PriorityList nézetösszetevővé válik, amely priority-list lesz. A nézetösszetevő paramétereit a rendszer attribútumként adja át a kebab-esetben.

Nézetösszetevő meghívása közvetlenül egy vezérlőből

A nézetösszetevők általában egy nézetből hívhatók meg, de közvetlenül egy vezérlőmetódusból hívhatók meg. Bár a nézetösszetevők nem határoznak meg olyan végpontokat, mint a vezérlők, egy vezérlőművelet implementálható, amely egy adott ViewComponentResult tartalom tartalmát adja vissza.

A következő példában a nézetösszetevőt közvetlenül a vezérlőből hívjuk meg:

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

Alapszintű nézetösszetevő létrehozása

Töltse le, készítse el és tesztelje a kezdőkódot. Ez egy alapszintű projekt egy ToDo vezérlővel, amely megjeleníti a ToDo-elemek listáját.

ToDos-lista

A vezérlő frissítése a prioritás és a befejezés állapotának átadása érdekében

Frissítse a metódust a Index prioritási és befejezési állapot paramétereinek használatára:

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);
    }

ViewComponent-osztály hozzáadása

ViewComponent-osztály hozzáadása a következőhöz 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();
    }
}

Megjegyzések a kódhoz:

  • Az összetevőosztályok megtekintése a projekt bármely mappájában megtalálható.

  • Mivel a PriorityListViewComponent osztálynév a ViewComponent utótaggal végződik, a futtatókörnyezet a sztringet PriorityList használja, amikor egy nézetből hivatkozik az osztály összetevőjére.

  • Az [ViewComponent] attribútum megváltoztathatja a nézetösszetevőre való hivatkozáshoz használt nevet. Például az osztály lehetett volna a következő attribútummal megnevezve: XYZ[ViewComponent].

    [ViewComponent(Name = "PriorityList")]
       public class XYZ : ViewComponent
    
  • Az [ViewComponent] előző kódban szereplő attribútum a nézetösszetevő-választót a következőre utasítja:

    • Amikor a PriorityList nevet használja az összetevőhöz kapcsolódó nézetek keresésére
    • A "PriorityList" sztring, amikor az osztályösszetevőre hivatkozik egy nézetből.
  • Az összetevő függőséginjektálás használatával teszi elérhetővé az adatkörnyezetet.

  • InvokeAsync egy nézetből meghívható metódust tesz elérhetővé, és tetszőleges számú argumentumot vehet igénybe.

  • A InvokeAsync metódus visszaadja a ToDo halmazt, amely elemek megfelelnek a isDone és maxPriority paramétereknek.

A nézetösszetevő Razor nézet létrehozása

  • Hozza létre a Nézetek/Megosztott/Összetevők mappát. Ennek a mappának Componentskell lennie.

  • Hozza létre a Views/Shared/Components/PriorityList mappát. Ennek a mappanévnek meg kell egyeznie a nézetösszetevő-osztály nevével, vagy az osztály nevével, az utótag nélkül. Ha az ViewComponent attribútumot használja, az osztály nevének meg kell egyeznie az attribútum megjelölésével.

  • Views/Shared/Components/PriorityList/Default.cshtml Razor Nézet létrehozása:

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

    A Razor nézet felsorolja TodoItem és megjeleníti őket. Ha a nézetösszetevő InvokeAsync metódus nem felel meg a nézet nevének, a nézet neve konvenciók szerint az Alapértelmezett értéket használja. Egy adott vezérlő alapértelmezett stílusának felülbírálásához adjon hozzá egy nézetet a vezérlőspecifikus nézetmappához (például Nézetek/ToDo/Components/PriorityList/Default.cshtml).

    Ha a nézetösszetevő vezérlőspecifikus, hozzáadható a vezérlőspecifikus mappához. Például Views/ToDo/Components/PriorityList/Default.cshtml vezérlőspecifikus.

  • Adjon hozzá egy div hívást a prioritáslista összetevőhöz a Views/ToDo/index.cshtml fájl aljára:

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

A korrektúra @await Component.InvokeAsync a nézetösszetevők hívásának szintaxisát jeleníti meg. Az első argumentum a meghívni vagy hívni kívánt összetevő neve. A rendszer további paramétereket ad át az összetevőnek. InvokeAsync tetszőleges számú argumentumot vehet fel.

Tesztelje az alkalmazást. Az alábbi képen a ToDo lista és a prioritási elemek láthatók:

teendőlista és prioritáselemek

A nézetösszetevő közvetlenül a vezérlőből hívható meg:

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

prioritási elemek az IndexVC műveletből

Nézetösszetevő nevének megadása

Előfordulhat, hogy egy összetett nézetösszetevőnek bizonyos feltételek mellett nem alapértelmezett nézetet kell megadnia. Az alábbi kód bemutatja, hogyan adhatja meg a "PVC" nézetet a InvokeAsync metódusból. Frissítse a metódust InvokeAsync az PriorityListViewComponent osztályban.

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);
}

Másolja a Views/Shared/Components/PriorityList/Default.cshtml fájlt egy nevesített Views/Shared/Components/PriorityList/PVC.cshtmlnézetbe. Adjon hozzá egy címsort, amely jelzi, hogy a PVC-nézet használatban van.

@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>

Futtassa az alkalmazást, és ellenőrizze a PVC nézetet.

Prioritás nézet komponens

Ha a PVC nézet nem jelenik meg, ellenőrizze, hogy a nézetösszetevő 4 vagy annál magasabb prioritással van-e meghívva.

A nézet elérési útjának vizsgálata

  • Módosítsa a prioritási paramétert három vagy kevesebbre, hogy a prioritási nézet ne legyen visszaadva.

  • Ideiglenesen nevezze át a Views/ToDo/Components/PriorityList/Default.cshtml következőre: 1Default.cshtml.

  • Tesztelje az alkalmazást, a következő hiba történik:

    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
    
  • Másolja át a következőt: Views/ToDo/Components/PriorityList/1Default.cshtml ide: Views/Shared/Components/PriorityList/Default.cshtml.

  • Adjon hozzá néhány korrektúrát a Megosztott toDo nézet összetevő nézetéhez, hogy jelezze, hogy a nézet a Megosztott mappából származik.

  • Tesztelje a Megosztott összetevő nézetet.

ToDo kimenet megosztott összetevő nézettel

A kódolt sztringek elkerülése

A fordítási idő biztonsága érdekében cserélje le a hard-coded view összetevő nevét az osztálynévre. Frissítse a PriorityListViewComponent.cs fájlt úgy, hogy ne használja a "ViewComponent" utótagot:

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();
    }
}

A nézetfájl:

</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>

A Component.InvokeAsync metódus túlterhelése, amely egy CLR típust vesz át, a typeof operátort használja.

</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>

Szinkron munka végrehajtása

A keretrendszer kezeli a szinkron Invoke metódus meghívását, ha nincs szükség aszinkron munkára. A következő metódus létrehoz egy szinkron Invoke nézetösszetevőt:

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);
        }
    }
}

A nézetösszetevő fájlja Razor :

<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>

A nézetösszetevőt egy Razor fájlban (például Views/Home/Index.cshtml) hívja meg a rendszer az alábbi módszerek egyikével:

A IViewComponentHelper megközelítés használatához hívja meg a Component.InvokeAsync-t.

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

A Címkesegítő használatához regisztrálja a Nézet összetevőt tartalmazó szerelvényt az @addTagHelper irányelv használatával (a nézetösszetevő egy úgynevezett MyWebAppszerelvényben található):

@addTagHelper *, MyWebApp

A Razor jelölőfájlban használja a View Component Tag Helper-t.

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

A PriorityList.Invoke metódus aláírása szinkron, de a Razor megkeresi és meghívja a metódust a Component.InvokeAsync jelölőfájlban.

További erőforrások

Mintakód megtekintése vagy letöltése (hogyan töltsd le)

Összetevők megtekintése

A nézetösszetevők hasonlóak a részleges nézetekhez, de sokkal hatékonyabbak. A nézetösszetevők nem használnak modellkötést, és csak a behíváskor megadott adatoktól függenek. Ez a cikk vezérlők és nézetek használatával készült, de a nézetösszetevők a Pages szolgáltatással Razor is működnek.

Nézetösszetevő:

  • Egy adattömb megjelenítése teljes válasz helyett.
  • Ugyanolyan felelősségek elkülönítését és tesztelhetőségi előnyöket kínál, mint a vezérlő és a nézet között.
  • Paraméterekkel és üzleti logikával rendelkezhet.
  • Általában egy elrendezési oldalról hívjuk meg.

A nézetkomponensek bárhol használhatók, ahol újrafelhasználható renderelési logikára van szükség, amely túl összetett egy részleges nézethez, például:

  • Dinamikus navigációs menük
  • Címkefelhő (ahol az adatbázist lekérdezi)
  • Bejelentkezési panel
  • Bevásárlókocsi
  • Nemrég közzétett cikkek
  • Oldalsáv tartalma egy tipikus blogon
  • Egy bejelentkezési panel, amely minden oldalon megjelenik, és a felhasználó bejelentkezési állapotától függően megjeleníti a kijelentkezésre vagy a bejelentkezésre mutató hivatkozásokat

A nézetösszetevő két részből áll: az osztályból (amely általában a ViewComponent-ből származik) és az eredményből, amit visszaad (ami általában egy nézet). A vezérlőkhöz hasonlóan a nézetösszetevők is lehetnek POCO-k, de a fejlesztők többsége kihasználja az elérhető ViewComponentmódszereket és tulajdonságokat.

Ha azt mérlegeli, hogy a megjelenítési összetevők megfelelnek-e az alkalmazás specifikációinak, érdemes megfontolni a összetevők alkalmazását helyettük. Razor az összetevők a korrektúra és a C#-kód kombinálásával újrahasználható felhasználói felületi egységeket hoznak létre. Razor az összetevőket úgy tervezték, hogy az ügyféloldali felhasználói felület logikájának és összetételének biztosításakor a fejlesztői hatékonyságot szolgálják. További információ: ASP.NET Core-összetevőkRazor. Az összetevők MVC- vagy Pages-alkalmazásokba való beépítésére Razor vonatkozó információkért lásd: Razor.Razor

Nézetösszetevő létrehozása

Ez a szakasz a nézetösszetevő létrehozásának magas szintű követelményeit tartalmazza. A cikk későbbi részében részletesen megvizsgáljuk az egyes lépéseket, és létrehozunk egy nézetösszetevőt.

A nézet összetevőosztálya

A nézetösszetevő-osztályt az alábbiak bármelyike hozhatja létre:

  • Származtatás a ViewComponentből
  • Az osztály díszítése az [ViewComponent] attribútummal, vagy egy [ViewComponent] attribútummal rendelkező osztályból való származtatással
  • Olyan osztály létrehozása, amelyben a név a ViewComponent utótaggal végződik

A vezérlőkhöz hasonlóan a nézetösszetevőknek nyilvánosnak, nem beágyazottnak és nem absztrakt osztályoknak kell lenniük. A nézetkomponens neve az osztály neve, amelyből eltávolítottuk a "ViewComponent" utótagot. A ViewComponentAttribute.Name tulajdonság explicit módon is megadható.

Nézetösszetevő-osztály:

Ha meg szeretné akadályozni, hogy egy kis- és nagybetűkre érzéketlen ViewComponent utótaggal rendelkező osztály nézetösszetevőként legyen kezelve, a [NonViewComponent] attribútummal lássa el az osztályt.

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

Összetevők metódusának megtekintése

A nézetösszetevő a logikáját egy olyan InvokeAsync metódusban határozza meg, amely vagy egy Task<IViewComponentResult>-t ad vissza, vagy egy szinkron Invoke metódusban, amely egy IViewComponentResult-t ad vissza. A paraméterek közvetlenül a nézetösszetevő meghívásából származnak, nem a modellkötésből. A nézetösszetevők soha nem kezelik közvetlenül a kéréseket. A nézet komponens általában inicializál egy modellt, és a View metódus meghívásával adja át azt egy nézetnek. Összefoglalva, tekintse meg az összetevők metódusát:

  • Definiáljon egy InvokeAsync metódust, amely egy Task<IViewComponentResult>-ot ad vissza, vagy egy szinkron Invoke metódust, amely egy IViewComponentResult-t ad vissza.
  • Általában egy modellt inicializál, majd a metódus ViewComponentView hívásával továbbítja azt egy nézetnek.
  • A paraméterek a hívó metódusból származnak, nem a HTTP-ből. Nincs modellkötés.
  • Nem érhető el közvetlenül HTTP-végpontként. A rendszer meghívja őket a kódból (általában nézetben). A nézetösszetevők soha nem kezelik a kéréseket.
  • A túlterhelés az aláíráson van, nem pedig az aktuális HTTP-kérés részletein.

Keresési útvonal megtekintése

A futtatókörnyezet a következő útvonalakon keresi a nézetet:

  • /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}

A keresési útvonal a vezérlőket és nézeteket, valamint Razor oldalakat használó projektekre vonatkozik.

A nézetösszetevő alapértelmezett nézetneve az Alapértelmezett, ami azt jelenti, hogy a nézetfájl neve általában el lesz nevezve Default.cshtml. A nézetösszetevő eredményének létrehozásakor vagy a View metódus meghívásakor eltérő nézetnevet adhat meg.

Javasoljuk, hogy nevezze el a nézetfájlt Default.cshtml , és használja a Nézetek/Megosztott/Összetevők/{Összetevő neve}/{Nézet neve} elérési utat. Az ebben a mintában használt PriorityList nézetösszetevő Views/Shared/Components/PriorityList/Default.cshtml használ a megjelenítéshez.

A nézet keresési útvonalának testreszabása

A nézet keresési útvonalának testreszabásához módosítsa a Razor gyűjtemény ViewLocationFormats-jét. Ha például a "/Components/{View Component Name}/{View Component Name}/{View Name} útvonalon belül szeretne nézeteket keresni, adjon hozzá egy új elemet a gyűjteményhez:

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

Az előző kódban a "{0}" helyőrző a "Components/{View Component Name}/{View Name}" elérési utat jelöli.

Nézetösszetevő meghívása

A nézetösszetevő használatához hívja meg a következőt egy nézeten belül:

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

A paramétereket a rendszer átadja a InvokeAsync metódusnak. A PriorityList cikkben kifejlesztett nézetösszetevő meghívása a Views/ToDo/Index.cshtml nézetfájlból történik. Az alábbiakban a InvokeAsync metódust két paraméterrel hívjuk meg:

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

Nézetösszetevő meghívása címkesegítőként

A ASP.NET Core 1.1 és újabb verziók esetén egy nézetösszetevőt hívhat meg címkesegítőként:

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

A Tag Helpers pascal-cased osztály- és metódusparaméterei a kebab-esetükre lesznek lefordítva. A nézetösszetevő meghívásához használt címkesegítő az <vc></vc> elemet használja. A nézetösszetevő a következőképpen van megadva:

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

Ha egy nézetösszetevőt címkesegítőként szeretne használni, regisztrálja a nézetösszetevőt tartalmazó szerelvényt az @addTagHelper irányelv használatával. Ha a nézetösszetevő egy úgynevezett MyWebAppszerelvényben található, adja hozzá a következő irányelvet a _ViewImports.cshtml fájlhoz:

@addTagHelper *, MyWebApp

A nézetösszetevőt címke-segédként regisztrálhatja a nézetösszetevőre hivatkozó bármely fájlra. A címkesegítők regisztrálásáról további információt a Címkesegítő hatókör kezelése című témakörben talál.

Az InvokeAsync oktatóanyagban használt módszer:

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

A Tag Helper jelölőnyelvben:

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

A fenti mintában a PriorityList nézetösszetevő lesz priority-list. A nézetösszetevő paramétereit a rendszer attribútumként adja át a kebab-esetben.

Nézetösszetevő meghívása közvetlenül egy vezérlőből

A nézetösszetevőket általában egy nézetből hívjuk meg, de közvetlenül egy vezérlőmetódusból hívhatja meg őket. Bár a nézetösszetevők nem definiálnak olyan végpontokat, mint a vezérlők, egyszerűen implementálhat egy vezérlőműveletet, amely visszaadja egy adott elem tartalmát ViewComponentResult.

Ebben a példában a nézetösszetevőt közvetlenül a vezérlőből hívjuk meg:

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

Útmutató: Egyszerű nézetösszetevő létrehozása

Töltse le, készítse el és tesztelje a kezdőkódot. Ez egy egyszerű projekt egy ToDo vezérlővel, amely megjeleníti a ToDo-elemek listáját.

ToDos-lista

ViewComponent-osztály hozzáadása

Hozzon létre egy ViewComponents mappát, és adja hozzá a következő PriorityListViewComponent osztályt:

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();
        }
    }
}

Megjegyzések a kódhoz:

  • Az összetevőosztályok megtekintése a projekt bármely mappájában megtalálható.

  • Mivel a PriorityListViewComponent osztálynév a ViewComponent utótaggal végződik, a futtatókörnyezet a sztringet PriorityList használja, amikor egy nézetből hivatkozik az osztály összetevőjére.

  • Az [ViewComponent] attribútum megváltoztathatja a nézetösszetevőre való hivatkozáshoz használt nevet. Előfordulhat például, hogy az osztály neve a XYZ következő attribútummal lett volna elnevezveViewComponent:

    [ViewComponent(Name = "PriorityList")]
       public class XYZ : ViewComponent
    
  • Az [ViewComponent] előző kódban szereplő attribútum a nézetösszetevő-választót a következőre utasítja:

    • Amikor a PriorityList nevet használja az összetevőhöz kapcsolódó nézetek keresésére
    • A "PriorityList" sztring, amikor az osztályösszetevőre hivatkozik egy nézetből.
  • Az összetevő függőséginjektálás használatával teszi elérhetővé az adatkörnyezetet.

  • InvokeAsync egy nézetből meghívható metódust tesz elérhetővé, és tetszőleges számú argumentumot vehet igénybe.

  • A InvokeAsync metódus visszaadja a ToDo halmazt, amely elemek megfelelnek a isDone és maxPriority paramétereknek.

A nézetösszetevő Razor nézet létrehozása

  • Hozza létre a Nézetek/Megosztott/Összetevők mappát. Ezt a mappát el kell nevezni Components.

  • Hozza létre a Views/Shared/Components/PriorityList mappát. Ennek a mappanévnek meg kell egyeznie a nézetösszetevő-osztály nevével, vagy az osztály nevével az utótag nélkül (ha konvenciót követtünk, és az osztálynévben a ViewComponent utótagot használtuk). Ha az ViewComponent attribútumot használta, az osztály nevének meg kell egyeznie az attribútum megjelölésével.

  • Views/Shared/Components/PriorityList/Default.cshtml Razor Nézet létrehozása:

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

    A Razor nézet felsorolja TodoItem és megjeleníti őket. Ha a nézetösszetevő InvokeAsync metódus nem adja meg a nézet nevét (mint a példánkban), akkor a rendszer konvenciók szerint az alapértelmezett értéket használja a nézetnévhez. Az oktatóanyag későbbi részében bemutatom, hogyan adhatja meg a nézet nevét. Egy adott vezérlő alapértelmezett stílusának felülbírálásához adjon hozzá egy nézetet a vezérlőspecifikus nézetmappához (például Nézetek/ToDo/Components/PriorityList/Default.cshtml).

    Ha a nézetösszetevő vezérlőspecifikus, hozzáadhatja a vezérlőspecifikus mappához (Views/ToDo/Components/PriorityList/Default.cshtml).

  • Adjon hozzá egy div hívást a prioritáslista összetevőhöz a Views/ToDo/index.cshtml fájl aljára:

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

A korrektúra @await Component.InvokeAsync a nézetösszetevők hívásának szintaxisát jeleníti meg. Az első argumentum a meghívni vagy hívni kívánt összetevő neve. A rendszer további paramétereket ad át az összetevőnek. InvokeAsync tetszőleges számú argumentumot vehet fel.

Tesztelje az alkalmazást. Az alábbi képen a ToDo lista és a prioritási elemek láthatók:

teendőlista és prioritáselemek

A nézetösszetevőt közvetlenül a vezérlőből is meghívhatja:

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

prioritási elemek az IndexVC műveletből

Nézetnév megadása

Előfordulhat, hogy egy összetett nézetösszetevőnek bizonyos feltételek mellett nem alapértelmezett nézetet kell megadnia. Az alábbi kód bemutatja, hogyan adhatja meg a "PVC" nézetet a InvokeAsync metódusból. Frissítse a metódust InvokeAsync az PriorityListViewComponent osztályban.

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);
}

Másolja a Views/Shared/Components/PriorityList/Default.cshtml fájlt egy nevesített Views/Shared/Components/PriorityList/PVC.cshtmlnézetbe. Adjon hozzá egy címsort, amely jelzi, hogy a PVC-nézet használatban van.

@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>

Frissítés Views/ToDo/Index.cshtml:

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

Futtassa az alkalmazást, és ellenőrizze a PVC nézetet.

Prioritás nézet komponens

Ha a PVC-nézet nem jelenik meg, ellenőrizze, hogy 4 vagy annál magasabb prioritású nézetösszetevőt hív-e meg.

A nézet elérési útjának vizsgálata

  • Módosítsa a prioritási paramétert három vagy kevesebbre, hogy a prioritási nézet ne legyen visszaadva.

  • Ideiglenesen nevezze át a Views/ToDo/Components/PriorityList/Default.cshtml következőre: 1Default.cshtml.

  • Tesztelje az alkalmazást, a következő hibaüzenet jelenik meg:

    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
    
  • Másolja át a következőt: Views/ToDo/Components/PriorityList/1Default.cshtml ide: Views/Shared/Components/PriorityList/Default.cshtml.

  • Adjon hozzá néhány korrektúrát a Megosztott toDo nézet összetevő nézetéhez, hogy jelezze, hogy a nézet a Megosztott mappából származik.

  • Tesztelje a Megosztott összetevő nézetet.

ToDo kimenet megosztott összetevő nézettel

A szigorúan kódolt sztringek elkerülése

Ha a fordítási idő biztonságára van szüksége, lecserélheti a rögzített nézet összetevőjének nevét az osztálynévre. Hozza létre a nézetösszetevőt a "ViewComponent" utótag nélkül:

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();
        }
    }
}

Adjon hozzá egy utasítást using a Razor nézetfájlhoz, és használja az operátort nameof :

@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>

A CLR típust fogadó Component.InvokeAsync metódus túlterhelését is használhatja. Ebben az esetben ne felejtse el használni az typeof operátort:

@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>

Szinkron munka végrehajtása

A keretrendszer kezeli a szinkron Invoke metódus meghívását, ha nem kell aszinkron munkát végeznie. A következő metódus létrehoz egy szinkron Invoke nézetösszetevőt:

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

A nézetösszetevő Razor fájlja felsorolja azokat a sztringeket, amelyeket a metódusnak adnak át Invoke (Views/Home/Components/PriorityList/Default.cshtml).

@model List<string>

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

A nézetösszetevőt egy Razor fájlban (például Views/Home/Index.cshtml) hívja meg a rendszer az alábbi módszerek egyikével:

A IViewComponentHelper megközelítés használatához hívja meg a Component.InvokeAsync-t.

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

A Címkesegítő használatához regisztrálja a Nézet összetevőt tartalmazó szerelvényt az @addTagHelper irányelv használatával (a nézetösszetevő egy úgynevezett MyWebAppszerelvényben található):

@addTagHelper *, MyWebApp

A Razor jelölőfájlban használja a View Component Tag Helper-t.

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

A PriorityList.Invoke metódus aláírása szinkron, de a Razor megkeresi és meghívja a metódust a Component.InvokeAsync jelölőfájlban.

Minden nézetösszetevő-paraméter megadása kötelező

A nézetösszetevő minden paramétere kötelező attribútum. Lásd ezt a GitHub-hibajegyet. Ha valamelyik paraméter nincs megadva:

  • A InvokeAsync metódus aláírása nem egyezik, ezért a metódus nem lesz végrehajtva.
  • A ViewComponent nem jelenít meg semmilyen jelölőnyelvi elemet.
  • A rendszer nem ad hibát.

További erőforrások