Lihat komponen di ASP.NET Core

Oleh Rick Anderson

Melihat komponen

Komponen tampilan mirip dengan tampilan parsial, tetapi jauh lebih kuat. Komponen tampilan tidak menggunakan pengikatan model, komponen tersebut bergantung pada data yang diteruskan saat memanggil komponen tampilan. Artikel ini ditulis menggunakan pengontrol dan tampilan, tetapi komponen tampilan berfungsi dengan Razor Pages.

Komponen tampilan:

  • Merender gugus daripada seluruh respons.
  • Mencakup pemisahan kekhawatiran dan manfaat uji coba yang sama yang ditemukan antara pengontrol dan tampilan.
  • Dapat memiliki parameter dan logika bisnis.
  • Biasanya dipanggil dari halaman tata letak.

Komponen tampilan dimaksudkan di mana saja logika penyajian yang dapat digunakan kembali yang terlalu kompleks untuk tampilan parsial, seperti:

  • Menu navigasi dinamis
  • Memberi tag cloud, tempatnya mengkueri database
  • Panel masuk
  • Keramaian belanja
  • Artikel yang baru-baru ini diterbitkan
  • Konten bilah sisi di blog
  • Panel masuk yang akan dirender di setiap halaman dan menampilkan tautan untuk keluar atau masuk, tergantung pada status masuk pengguna

Komponen tampilan terdiri dari dua bagian:

  • Kelas ini, biasanya berasal dari ViewComponent
  • Hasil yang dikembalikannya, biasanya tampilan.

Seperti pengontrol, komponen tampilan bisa menjadi POCO, tetapi sebagian besar pengembang memanfaatkan metode dan properti yang tersedia dengan berasal dari ViewComponent.

Saat mempertimbangkan apakah komponen tampilan memenuhi spesifikasi aplikasi, pertimbangkan untuk menggunakan Razor komponen sebagai gantinya. Razor komponen juga menggabungkan markup dengan kode C# untuk menghasilkan unit UI yang dapat digunakan kembali. Razor komponen dirancang untuk produktivitas pengembang saat menyediakan logika dan komposisi UI sisi klien. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor. Untuk informasi tentang cara menggabungkan Razor komponen ke dalam aplikasi MVC atau Razor Pages, lihat Mengintegrasikan komponen ASP.NET Core Razor ke dalam aplikasi ASP.NET Core.

Membuat komponen tampilan

Bagian ini berisi persyaratan tingkat tinggi untuk membuat komponen tampilan. Nantinya dalam artikel, kita akan memeriksa setiap langkah secara rinci dan membuat komponen tampilan.

Kelas komponen tampilan

Kelas komponen tampilan dapat dibuat oleh salah satu hal berikut:

Seperti pengontrol, komponen tampilan harus kelas publik, tidak bersarang, dan non-abstrak. Nama komponen tampilan adalah nama kelas dengan akhiran ViewComponent dihapus. Ini juga dapat ditentukan secara eksplisit menggunakan Name properti .

Kelas komponen tampilan:

  • Mendukung injeksi dependensi konstruktor
  • Tidak mengambil bagian dalam siklus hidup pengontrol, oleh karena itu filter tidak dapat digunakan dalam komponen tampilan

Untuk mencegah kelas yang memiliki akhiran tidak peka huruf besar/kecil ViewComponent diperlakukan sebagai komponen tampilan, hiasi kelas dengan [NonViewComponent] atribut :

using Microsoft.AspNetCore.Mvc;

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

Melihat metode komponen

Komponen tampilan mendefinisikan logikanya dalam:

  • InvokeAsync metode yang mengembalikan Task<IViewComponentResult>.
  • Invoke metode sinkron yang mengembalikan IViewComponentResult.

Parameter berasal langsung dari pemanggilan komponen tampilan, bukan dari pengikatan model. Komponen tampilan tidak pernah secara langsung menangani permintaan. Biasanya, komponen tampilan menginisialisasi model dan meneruskannya ke tampilan dengan memanggil View metode . Singkatnya, lihat metode komponen:

  • InvokeAsync Tentukan metode yang mengembalikan Task<IViewComponentResult> metode atau sinkron Invoke yang mengembalikan IViewComponentResult.
  • Biasanya menginisialisasi model dan meneruskannya ke tampilan dengan memanggil metode ViewComponent.View .
  • Parameter berasal dari metode panggilan, bukan HTTP. Tidak ada pengikatan model.
  • Tidak dapat dijangkau langsung sebagai titik akhir HTTP. Mereka biasanya dipanggil dalam tampilan. Komponen tampilan tidak pernah menangani permintaan.
  • Kelebihan beban pada tanda tangan daripada detail apa pun dari permintaan HTTP saat ini.

Lihat jalur pencarian

Runtime mencari tampilan di jalur berikut:

  • /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}
  • /Area/{Nama Area}/Tampilan/Bersama/Komponen/{Lihat Nama Komponen}/{Nama Tampilan}

Jalur pencarian berlaku untuk proyek menggunakan pengontrol + tampilan dan Razor Halaman.

Nama tampilan default untuk komponen tampilan adalah Default, yang berarti file tampilan biasanya akan diberi nama Default.cshtml. Nama tampilan yang berbeda dapat ditentukan saat membuat hasil komponen tampilan atau saat memanggil View metode .

Sebaiknya beri nama file Default.cshtml tampilan dan menggunakan jalur Views/Shared/Components/{View Component Name}/{View Name} . Komponen PriorityList tampilan yang digunakan dalam sampel ini menggunakan Views/Shared/Components/PriorityList/Default.cshtml untuk tampilan komponen tampilan.

Mengkustomisasi jalur pencarian tampilan

Untuk mengkustomisasi jalur pencarian tampilan, ubah RazorViewLocationFormats koleksi. Misalnya, untuk mencari tampilan di dalam jalur /Components/{View Component Name}/{View Name}, tambahkan item baru ke koleksi:

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.

Dalam kode sebelumnya, tempat penampung {0} mewakili jalur Components/{View Component Name}/{View Name}.

Memanggil komponen tampilan

Untuk menggunakan komponen tampilan, panggil yang berikut ini di dalam tampilan:

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

Parameter diteruskan ke InvokeAsync metode . Komponen PriorityList tampilan yang dikembangkan dalam artikel dipanggil dari Views/ToDo/Index.cshtml file tampilan. Dalam kode berikut, InvokeAsync metode ini dipanggil dengan dua parameter:

</table>

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

Memanggil komponen tampilan sebagai Pembantu Tag

Komponen Tampilan dapat dipanggil sebagai Pembantu Tag:

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

Parameter metode dan kelas kasus Pascal untuk Pembantu Tag diterjemahkan ke dalam kasus kebab mereka. Tag Helper untuk memanggil komponen tampilan menggunakan <vc></vc> elemen . Komponen tampilan ditentukan sebagai berikut:

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

Untuk menggunakan komponen tampilan sebagai Pembantu Tag, daftarkan rakitan yang berisi komponen tampilan menggunakan direktif @addTagHelper . Jika komponen tampilan berada dalam rakitan yang disebut MyWebApp, tambahkan direktif berikut ke _ViewImports.cshtml file:

@addTagHelper *, MyWebApp

Komponen tampilan dapat didaftarkan sebagai Pembantu Tag ke file apa pun yang mereferensikan komponen tampilan. Lihat Mengelola Cakupan Pembantu Tag untuk informasi selengkapnya tentang cara mendaftarkan Pembantu Tag.

Metode yang InvokeAsync digunakan dalam tutorial ini:

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

Dalam markup sebelumnya, PriorityList komponen tampilan menjadi priority-list. Parameter untuk komponen tampilan diteruskan sebagai atribut dalam kasus kebab.

Memanggil komponen tampilan langsung dari pengontrol

Komponen tampilan biasanya dipanggil dari tampilan, tetapi dapat dipanggil langsung dari metode pengontrol. Meskipun komponen tampilan tidak menentukan titik akhir seperti pengontrol, tindakan pengontrol yang mengembalikan konten ViewComponentResult dapat diimplementasikan.

Dalam contoh berikut, komponen tampilan dipanggil langsung dari pengontrol:

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

Membuat komponen tampilan dasar

Unduh, bangun, dan uji kode pemula. Ini adalah proyek dasar dengan ToDo pengontrol yang menampilkan daftar item ToDo .

List of ToDos

Memperbarui pengontrol untuk meneruskan status prioritas dan penyelesaian

Index Perbarui metode untuk menggunakan parameter status prioritas dan penyelesaian:

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

Menambahkan kelas ViewComponent

Tambahkan kelas ViewComponent ke 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();
    }
}

Catatan tentang kode:

  • Melihat kelas komponen dapat dimuat dalam folder apa pun dalam proyek.

  • Karena nama kelas PriorityListViewComponent diakhiri dengan akhiran ViewComponent, runtime menggunakan string PriorityList saat mereferensikan komponen kelas dari tampilan.

  • Atribut [ViewComponent] dapat mengubah nama yang digunakan untuk mereferensikan komponen tampilan. Misalnya, kelas dapat dinamai XYZ dengan atribut berikut [ViewComponent] :

    [ViewComponent(Name = "PriorityList")]
       public class XYZ : ViewComponent
    
  • Atribut [ViewComponent] dalam kode sebelumnya memberi tahu pemilih komponen tampilan untuk digunakan:

    • Nama PriorityList saat mencari tampilan yang terkait dengan komponen
    • String "PriorityList" saat mereferensikan komponen kelas dari tampilan.
  • Komponen menggunakan injeksi dependensi untuk membuat konteks data tersedia.

  • InvokeAsync memaparkan metode yang dapat dipanggil dari tampilan, dan dapat mengambil jumlah argumen arbitrer.

  • Metode mengembalikan InvokeAsync sekumpulan ToDo item yang memenuhi isDone parameter dan maxPriority .

Membuat tampilan komponen Razor tampilan

  • Buat folder Views/Shared/Components. Folder ini harus bernama Komponen.

  • Buat folder Views/Shared/Components/PriorityList. Nama folder ini harus cocok dengan nama kelas komponen tampilan, atau nama kelas dikurangi akhiran. ViewComponent Jika atribut digunakan, nama kelas harus cocok dengan penunjukan atribut.

  • Membuat Views/Shared/Components/PriorityList/Default.cshtmlRazor tampilan:

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

    Tampilan Razor mengambil daftar TodoItem dan menampilkannya. Jika metode komponen InvokeAsync tampilan tidak meneruskan nama tampilan, Default digunakan untuk nama tampilan menurut konvensi. Untuk mengganti gaya default untuk pengontrol tertentu, tambahkan tampilan ke folder tampilan khusus pengontrol (misalnya Views/ToDo/Components/PriorityList/Default.cshtml).

    Jika komponen tampilan khusus pengontrol, komponen tersebut dapat ditambahkan ke folder khusus pengontrol. Misalnya, Views/ToDo/Components/PriorityList/Default.cshtml khusus pengontrol.

  • Tambahkan panggilan yang div berisi ke komponen daftar prioritas ke bagian Views/ToDo/index.cshtml bawah file:

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

Markup @await Component.InvokeAsync menunjukkan sintaks untuk memanggil komponen tampilan. Argumen pertama adalah nama komponen yang ingin kita panggil atau panggil. Parameter berikutnya diteruskan ke komponen. InvokeAsync dapat mengambil jumlah argumen arbitrer.

Menguji aplikasi. Gambar berikut menunjukkan daftar ToDo dan item prioritas:

todo list and priority items

Komponen tampilan dapat dipanggil langsung dari pengontrol:

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

priority items from IndexVC action

Tentukan nama komponen tampilan

Komponen tampilan kompleks mungkin perlu menentukan tampilan non-default dalam beberapa kondisi. Kode berikut menunjukkan cara menentukan tampilan "PVC" dari InvokeAsync metode . InvokeAsync Perbarui metode di PriorityListViewComponent kelas .

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 Salin file ke tampilan bernama Views/Shared/Components/PriorityList/PVC.cshtml. Tambahkan judul untuk menunjukkan tampilan PVC sedang digunakan.

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

Jalankan aplikasi dan verifikasi tampilan PVC.

Priority View Component

Jika tampilan PVC tidak dirender, verifikasi komponen tampilan dengan prioritas 4 atau lebih tinggi dipanggil.

Memeriksa jalur tampilan

  • Ubah parameter prioritas menjadi tiga atau kurang sehingga tampilan prioritas tidak dikembalikan.

  • Ganti nama untuk 1Default.cshtmlsementara menjadi Views/ToDo/Components/PriorityList/Default.cshtml .

  • Uji aplikasi, kesalahan berikut terjadi:

    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
    
  • Salin Views/ToDo/Components/PriorityList/1Default.cshtml ke Views/Shared/Components/PriorityList/Default.cshtml.

  • Tambahkan beberapa markup ke tampilan komponen tampilan ToDo Bersama untuk menunjukkan tampilan berasal dari folder Bersama .

  • Uji tampilan Komponen bersama.

ToDo output with Shared component view

Hindari string yang dikodekan secara permanen

Untuk keamanan waktu kompilasi, ganti nama komponen tampilan yang dikodekan secara permanen dengan nama kelas. Perbarui file PriorityListViewComponent.cs untuk tidak menggunakan akhiran "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();
    }
}

File tampilan :

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

Kelebihan metode Component.InvokeAsync yang mengambil jenis CLR menggunakan typeof operator:

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

Melakukan pekerjaan sinkron

Kerangka kerja menangani pemanggilan metode sinkron Invoke jika pekerjaan asinkron tidak diperlukan. Metode berikut membuat komponen tampilan sinkron Invoke :

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

File komponen Razor tampilan:

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

Komponen tampilan dipanggil dalam Razor file (misalnya, Views/Home/Index.cshtml) menggunakan salah satu pendekatan berikut:

Untuk menggunakan IViewComponentHelper pendekatan, panggil Component.InvokeAsync:

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

Untuk menggunakan Pembantu Tag, daftarkan rakitan yang berisi Komponen Tampilan menggunakan @addTagHelper direktif (komponen tampilan berada dalam rakitan yang disebut MyWebApp):

@addTagHelper *, MyWebApp

Gunakan Komponen tampilan Tag Helper dalam Razor file markup:

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

Tanda tangan PriorityList.Invoke metode sinkron, tetapi Razor menemukan dan memanggil metode dengan Component.InvokeAsync dalam file markup.

Sumber Daya Tambahan:

Melihat komponen

Komponen tampilan mirip dengan tampilan parsial, tetapi jauh lebih kuat. Komponen tampilan tidak menggunakan pengikatan model, komponen tersebut bergantung pada data yang diteruskan saat memanggil komponen tampilan. Artikel ini ditulis menggunakan pengontrol dan tampilan, tetapi komponen tampilan berfungsi dengan Razor Pages.

Komponen tampilan:

  • Merender gugus daripada seluruh respons.
  • Mencakup pemisahan kekhawatiran dan manfaat uji coba yang sama yang ditemukan antara pengontrol dan tampilan.
  • Dapat memiliki parameter dan logika bisnis.
  • Biasanya dipanggil dari halaman tata letak.

Komponen tampilan dimaksudkan di mana saja logika penyajian yang dapat digunakan kembali yang terlalu kompleks untuk tampilan parsial, seperti:

  • Menu navigasi dinamis
  • Memberi tag cloud, tempatnya mengkueri database
  • Panel masuk
  • Keramaian belanja
  • Artikel yang baru-baru ini diterbitkan
  • Konten bilah sisi di blog
  • Panel masuk yang akan dirender di setiap halaman dan menampilkan tautan untuk keluar atau masuk, tergantung pada status masuk pengguna

Komponen tampilan terdiri dari dua bagian:

  • Kelas ini, biasanya berasal dari ViewComponent
  • Hasil yang dikembalikannya, biasanya tampilan.

Seperti pengontrol, komponen tampilan bisa menjadi POCO, tetapi sebagian besar pengembang memanfaatkan metode dan properti yang tersedia dengan berasal dari ViewComponent.

Saat mempertimbangkan apakah komponen tampilan memenuhi spesifikasi aplikasi, pertimbangkan untuk menggunakan Razor komponen sebagai gantinya. Razor komponen juga menggabungkan markup dengan kode C# untuk menghasilkan unit UI yang dapat digunakan kembali. Razor komponen dirancang untuk produktivitas pengembang saat menyediakan logika dan komposisi UI sisi klien. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor. Untuk informasi tentang cara menggabungkan Razor komponen ke dalam aplikasi MVC atau Razor Pages, lihat Merender dan mengintegrasikan komponen ASP.NET CoreRazor.

Membuat komponen tampilan

Bagian ini berisi persyaratan tingkat tinggi untuk membuat komponen tampilan. Nantinya dalam artikel, kita akan memeriksa setiap langkah secara rinci dan membuat komponen tampilan.

Kelas komponen tampilan

Kelas komponen tampilan dapat dibuat oleh salah satu hal berikut:

Seperti pengontrol, komponen tampilan harus kelas publik, tidak bersarang, dan non-abstrak. Nama komponen tampilan adalah nama kelas dengan akhiran ViewComponent dihapus. Ini juga dapat ditentukan secara eksplisit menggunakan Name properti .

Kelas komponen tampilan:

  • Mendukung injeksi dependensi konstruktor
  • Tidak mengambil bagian dalam siklus hidup pengontrol, oleh karena itu filter tidak dapat digunakan dalam komponen tampilan

Untuk mencegah kelas yang memiliki akhiran tidak peka huruf besar/kecil ViewComponent diperlakukan sebagai komponen tampilan, hiasi kelas dengan [NonViewComponent] atribut :

using Microsoft.AspNetCore.Mvc;

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

Melihat metode komponen

Komponen tampilan mendefinisikan logikanya dalam:

  • InvokeAsync metode yang mengembalikan Task<IViewComponentResult>.
  • Invoke metode sinkron yang mengembalikan IViewComponentResult.

Parameter berasal langsung dari pemanggilan komponen tampilan, bukan dari pengikatan model. Komponen tampilan tidak pernah secara langsung menangani permintaan. Biasanya, komponen tampilan menginisialisasi model dan meneruskannya ke tampilan dengan memanggil View metode . Singkatnya, lihat metode komponen:

  • InvokeAsync Tentukan metode yang mengembalikan Task<IViewComponentResult> metode atau sinkron Invoke yang mengembalikan IViewComponentResult.
  • Biasanya menginisialisasi model dan meneruskannya ke tampilan dengan memanggil metode ViewComponent.View .
  • Parameter berasal dari metode panggilan, bukan HTTP. Tidak ada pengikatan model.
  • Tidak dapat dijangkau langsung sebagai titik akhir HTTP. Mereka biasanya dipanggil dalam tampilan. Komponen tampilan tidak pernah menangani permintaan.
  • Kelebihan beban pada tanda tangan daripada detail apa pun dari permintaan HTTP saat ini.

Lihat jalur pencarian

Runtime mencari tampilan di jalur berikut:

  • /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}
  • /Area/{Nama Area}/Tampilan/Bersama/Komponen/{Lihat Nama Komponen}/{Nama Tampilan}

Jalur pencarian berlaku untuk proyek menggunakan pengontrol + tampilan dan Razor Halaman.

Nama tampilan default untuk komponen tampilan adalah Default, yang berarti file tampilan biasanya akan diberi nama Default.cshtml. Nama tampilan yang berbeda dapat ditentukan saat membuat hasil komponen tampilan atau saat memanggil View metode .

Sebaiknya beri nama file Default.cshtml tampilan dan menggunakan jalur Views/Shared/Components/{View Component Name}/{View Name} . Komponen PriorityList tampilan yang digunakan dalam sampel ini menggunakan Views/Shared/Components/PriorityList/Default.cshtml untuk tampilan komponen tampilan.

Mengkustomisasi jalur pencarian tampilan

Untuk mengkustomisasi jalur pencarian tampilan, ubah RazorViewLocationFormats koleksi. Misalnya, untuk mencari tampilan di dalam jalur /Components/{View Component Name}/{View Name}, tambahkan item baru ke koleksi:

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.

Dalam kode sebelumnya, tempat penampung {0} mewakili jalur Components/{View Component Name}/{View Name}.

Memanggil komponen tampilan

Untuk menggunakan komponen tampilan, panggil yang berikut ini di dalam tampilan:

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

Parameter diteruskan ke InvokeAsync metode . Komponen PriorityList tampilan yang dikembangkan dalam artikel dipanggil dari Views/ToDo/Index.cshtml file tampilan. Dalam kode berikut, InvokeAsync metode ini dipanggil dengan dua parameter:

</table>

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

Memanggil komponen tampilan sebagai Pembantu Tag

Komponen Tampilan dapat dipanggil sebagai Pembantu Tag:

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

Parameter metode dan kelas kasus Pascal untuk Pembantu Tag diterjemahkan ke dalam kasus kebab mereka. Tag Helper untuk memanggil komponen tampilan menggunakan <vc></vc> elemen . Komponen tampilan ditentukan sebagai berikut:

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

Untuk menggunakan komponen tampilan sebagai Pembantu Tag, daftarkan rakitan yang berisi komponen tampilan menggunakan direktif @addTagHelper . Jika komponen tampilan berada dalam rakitan yang disebut MyWebApp, tambahkan direktif berikut ke _ViewImports.cshtml file:

@addTagHelper *, MyWebApp

Komponen tampilan dapat didaftarkan sebagai Pembantu Tag ke file apa pun yang mereferensikan komponen tampilan. Lihat Mengelola Cakupan Pembantu Tag untuk informasi selengkapnya tentang cara mendaftarkan Pembantu Tag.

Metode yang InvokeAsync digunakan dalam tutorial ini:

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

Dalam markup sebelumnya, PriorityList komponen tampilan menjadi priority-list. Parameter untuk komponen tampilan diteruskan sebagai atribut dalam kasus kebab.

Memanggil komponen tampilan langsung dari pengontrol

Komponen tampilan biasanya dipanggil dari tampilan, tetapi dapat dipanggil langsung dari metode pengontrol. Meskipun komponen tampilan tidak menentukan titik akhir seperti pengontrol, tindakan pengontrol yang mengembalikan konten ViewComponentResult dapat diimplementasikan.

Dalam contoh berikut, komponen tampilan dipanggil langsung dari pengontrol:

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

Membuat komponen tampilan dasar

Unduh, bangun, dan uji kode pemula. Ini adalah proyek dasar dengan ToDo pengontrol yang menampilkan daftar item ToDo .

List of ToDos

Memperbarui pengontrol untuk meneruskan status prioritas dan penyelesaian

Index Perbarui metode untuk menggunakan parameter status prioritas dan penyelesaian:

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

Menambahkan kelas ViewComponent

Tambahkan kelas ViewComponent ke 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();
    }
}

Catatan tentang kode:

  • Melihat kelas komponen dapat dimuat dalam folder apa pun dalam proyek.

  • Karena nama kelas PriorityListViewComponent diakhiri dengan akhiran ViewComponent, runtime menggunakan string PriorityList saat mereferensikan komponen kelas dari tampilan.

  • Atribut [ViewComponent] dapat mengubah nama yang digunakan untuk mereferensikan komponen tampilan. Misalnya, kelas dapat dinamai XYZ dengan atribut berikut [ViewComponent] :

    [ViewComponent(Name = "PriorityList")]
       public class XYZ : ViewComponent
    
  • Atribut [ViewComponent] dalam kode sebelumnya memberi tahu pemilih komponen tampilan untuk digunakan:

    • Nama PriorityList saat mencari tampilan yang terkait dengan komponen
    • String "PriorityList" saat mereferensikan komponen kelas dari tampilan.
  • Komponen menggunakan injeksi dependensi untuk membuat konteks data tersedia.

  • InvokeAsync memaparkan metode yang dapat dipanggil dari tampilan, dan dapat mengambil jumlah argumen arbitrer.

  • Metode mengembalikan InvokeAsync sekumpulan ToDo item yang memenuhi isDone parameter dan maxPriority .

Membuat tampilan komponen Razor tampilan

  • Buat folder Views/Shared/Components. Folder ini harus bernama Komponen.

  • Buat folder Views/Shared/Components/PriorityList. Nama folder ini harus cocok dengan nama kelas komponen tampilan, atau nama kelas dikurangi akhiran. ViewComponent Jika atribut digunakan, nama kelas harus cocok dengan penunjukan atribut.

  • Membuat Views/Shared/Components/PriorityList/Default.cshtmlRazor tampilan:

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

    Tampilan Razor mengambil daftar TodoItem dan menampilkannya. Jika metode komponen InvokeAsync tampilan tidak meneruskan nama tampilan, Default digunakan untuk nama tampilan menurut konvensi. Untuk mengganti gaya default untuk pengontrol tertentu, tambahkan tampilan ke folder tampilan khusus pengontrol (misalnya Views/ToDo/Components/PriorityList/Default.cshtml).

    Jika komponen tampilan khusus pengontrol, komponen tersebut dapat ditambahkan ke folder khusus pengontrol. Misalnya, Views/ToDo/Components/PriorityList/Default.cshtml khusus pengontrol.

  • Tambahkan panggilan yang div berisi ke komponen daftar prioritas ke bagian Views/ToDo/index.cshtml bawah file:

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

Markup @await Component.InvokeAsync menunjukkan sintaks untuk memanggil komponen tampilan. Argumen pertama adalah nama komponen yang ingin kita panggil atau panggil. Parameter berikutnya diteruskan ke komponen. InvokeAsync dapat mengambil jumlah argumen arbitrer.

Menguji aplikasi. Gambar berikut menunjukkan daftar ToDo dan item prioritas:

todo list and priority items

Komponen tampilan dapat dipanggil langsung dari pengontrol:

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

priority items from IndexVC action

Tentukan nama komponen tampilan

Komponen tampilan kompleks mungkin perlu menentukan tampilan non-default dalam beberapa kondisi. Kode berikut menunjukkan cara menentukan tampilan "PVC" dari InvokeAsync metode . InvokeAsync Perbarui metode di PriorityListViewComponent kelas .

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 Salin file ke tampilan bernama Views/Shared/Components/PriorityList/PVC.cshtml. Tambahkan judul untuk menunjukkan tampilan PVC sedang digunakan.

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

Jalankan aplikasi dan verifikasi tampilan PVC.

Priority View Component

Jika tampilan PVC tidak dirender, verifikasi komponen tampilan dengan prioritas 4 atau lebih tinggi dipanggil.

Memeriksa jalur tampilan

  • Ubah parameter prioritas menjadi tiga atau kurang sehingga tampilan prioritas tidak dikembalikan.

  • Ganti nama untuk 1Default.cshtmlsementara menjadi Views/ToDo/Components/PriorityList/Default.cshtml .

  • Uji aplikasi, kesalahan berikut terjadi:

    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
    
  • Salin Views/ToDo/Components/PriorityList/1Default.cshtml ke Views/Shared/Components/PriorityList/Default.cshtml.

  • Tambahkan beberapa markup ke tampilan komponen tampilan ToDo Bersama untuk menunjukkan tampilan berasal dari folder Bersama .

  • Uji tampilan Komponen bersama.

ToDo output with Shared component view

Hindari string yang dikodekan secara permanen

Untuk keamanan waktu kompilasi, ganti nama komponen tampilan yang dikodekan secara permanen dengan nama kelas. Perbarui file PriorityListViewComponent.cs untuk tidak menggunakan akhiran "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();
    }
}

File tampilan :

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

Kelebihan metode Component.InvokeAsync yang mengambil jenis CLR menggunakan typeof operator:

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

Melakukan pekerjaan sinkron

Kerangka kerja menangani pemanggilan metode sinkron Invoke jika pekerjaan asinkron tidak diperlukan. Metode berikut membuat komponen tampilan sinkron Invoke :

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

File komponen Razor tampilan:

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

Komponen tampilan dipanggil dalam Razor file (misalnya, Views/Home/Index.cshtml) menggunakan salah satu pendekatan berikut:

Untuk menggunakan IViewComponentHelper pendekatan, panggil Component.InvokeAsync:

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

Untuk menggunakan Pembantu Tag, daftarkan rakitan yang berisi Komponen Tampilan menggunakan @addTagHelper direktif (komponen tampilan berada dalam rakitan yang disebut MyWebApp):

@addTagHelper *, MyWebApp

Gunakan Komponen tampilan Tag Helper dalam Razor file markup:

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

Tanda tangan PriorityList.Invoke metode sinkron, tetapi Razor menemukan dan memanggil metode dengan Component.InvokeAsync dalam file markup.

Sumber Daya Tambahan:

Melihat atau mengunduh kode sampel (cara mengunduh)

Melihat komponen

Komponen tampilan mirip dengan tampilan parsial, tetapi jauh lebih kuat. Komponen tampilan tidak menggunakan pengikatan model, dan hanya bergantung pada data yang disediakan saat memanggilnya. Artikel ini ditulis menggunakan pengontrol dan tampilan, tetapi komponen tampilan juga berfungsi dengan Razor Pages.

Komponen tampilan:

  • Merender gugus daripada seluruh respons.
  • Mencakup pemisahan kekhawatiran dan manfaat uji coba yang sama yang ditemukan antara pengontrol dan tampilan.
  • Dapat memiliki parameter dan logika bisnis.
  • Biasanya dipanggil dari halaman tata letak.

Komponen tampilan dimaksudkan di mana saja Anda memiliki logika penyajian yang dapat digunakan kembali yang terlalu kompleks untuk tampilan parsial, seperti:

  • Menu navigasi dinamis
  • Tag cloud (tempatnya mengkueri database)
  • Panel masuk
  • Keramaian belanja
  • Artikel yang baru-baru ini diterbitkan
  • Konten bilah sisi di blog biasa
  • Panel masuk yang akan dirender di setiap halaman dan menampilkan tautan untuk keluar atau masuk, tergantung pada status masuk pengguna

Komponen tampilan terdiri dari dua bagian: kelas (biasanya berasal dari ViewComponent) dan hasilnya kembali (biasanya tampilan). Seperti pengontrol, komponen tampilan bisa menjadi POCO, tetapi sebagian besar pengembang memanfaatkan metode dan properti yang tersedia dengan berasal dari ViewComponent.

Saat mempertimbangkan apakah komponen tampilan memenuhi spesifikasi aplikasi, pertimbangkan untuk menggunakan Razor komponen sebagai gantinya. Razor komponen juga menggabungkan markup dengan kode C# untuk menghasilkan unit UI yang dapat digunakan kembali. Razor komponen dirancang untuk produktivitas pengembang saat menyediakan logika dan komposisi UI sisi klien. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor. Untuk informasi tentang cara menggabungkan Razor komponen ke dalam aplikasi MVC atau Razor Pages, lihat Merender dan mengintegrasikan komponen ASP.NET CoreRazor.

Membuat komponen tampilan

Bagian ini berisi persyaratan tingkat tinggi untuk membuat komponen tampilan. Nantinya dalam artikel, kita akan memeriksa setiap langkah secara rinci dan membuat komponen tampilan.

Kelas komponen tampilan

Kelas komponen tampilan dapat dibuat oleh salah satu hal berikut:

  • Berasal dari ViewComponent
  • Mendekorasi kelas dengan [ViewComponent] atribut , atau berasal dari kelas dengan [ViewComponent] atribut
  • Membuat kelas di mana nama diakhiri dengan akhiran ViewComponent

Seperti pengontrol, komponen tampilan harus kelas publik, tidak bersarang, dan non-abstrak. Nama komponen tampilan adalah nama kelas dengan akhiran "ViewComponent" dihapus. Ini juga dapat ditentukan secara eksplisit menggunakan ViewComponentAttribute.Name properti .

Kelas komponen tampilan:

  • Sepenuhnya mendukung injeksi dependensi konstruktor
  • Tidak mengambil bagian dalam siklus hidup pengontrol, yang berarti Anda tidak dapat menggunakan filter dalam komponen tampilan

Untuk menghentikan kelas yang memiliki akhiran ViewComponent yang tidak peka huruf besar/kecil agar tidak diperlakukan sebagai komponen tampilan, hiasi kelas dengan atribut [NonViewComponent]:

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

Melihat metode komponen

Komponen tampilan mendefinisikan logikanya dalam InvokeAsync metode yang mengembalikan Task<IViewComponentResult> atau dalam metode sinkron Invoke yang mengembalikan IViewComponentResult. Parameter berasal langsung dari pemanggilan komponen tampilan, bukan dari pengikatan model. Komponen tampilan tidak pernah secara langsung menangani permintaan. Biasanya, komponen tampilan menginisialisasi model dan meneruskannya ke tampilan dengan memanggil View metode . Singkatnya, lihat metode komponen:

  • InvokeAsync Tentukan metode yang mengembalikan Task<IViewComponentResult> metode atau sinkron Invoke yang mengembalikan IViewComponentResult.
  • Biasanya menginisialisasi model dan meneruskannya ke tampilan dengan memanggil ViewComponentView metode .
  • Parameter berasal dari metode panggilan, bukan HTTP. Tidak ada pengikatan model.
  • Tidak dapat dijangkau langsung sebagai titik akhir HTTP. Mereka dipanggil dari kode Anda (biasanya dalam tampilan). Komponen tampilan tidak pernah menangani permintaan.
  • Kelebihan beban pada tanda tangan daripada detail apa pun dari permintaan HTTP saat ini.

Lihat jalur pencarian

Runtime mencari tampilan di jalur berikut:

  • /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}
  • /Area/{Nama Area}/Tampilan/Bersama/Komponen/{Lihat Nama Komponen}/{Nama Tampilan}

Jalur pencarian berlaku untuk proyek menggunakan pengontrol + tampilan dan Razor Halaman.

Nama tampilan default untuk komponen tampilan adalah Default, yang berarti file tampilan Anda biasanya akan diberi nama Default.cshtml. Anda dapat menentukan nama tampilan yang berbeda saat membuat hasil komponen tampilan atau saat memanggil View metode .

Sebaiknya beri nama file Default.cshtml tampilan dan gunakan jalur Views/Shared/Components/{View Component Name}/{View Name} . Komponen PriorityList tampilan yang digunakan dalam sampel ini menggunakan Views/Shared/Components/PriorityList/Default.cshtml untuk tampilan komponen tampilan.

Mengkustomisasi jalur pencarian tampilan

Untuk mengkustomisasi jalur pencarian tampilan, ubah RazorViewLocationFormats koleksi. Misalnya, untuk mencari tampilan dalam jalur "/Components/{View Component Name}/{View Name}", tambahkan item baru ke koleksi:

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

Dalam kode sebelumnya, tempat penampung "{0}" mewakili jalur "Komponen/{Lihat Nama Komponen}/{Tampilkan Nama}".

Memanggil komponen tampilan

Untuk menggunakan komponen tampilan, panggil yang berikut ini di dalam tampilan:

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

Parameter akan diteruskan ke InvokeAsync metode . Komponen PriorityList tampilan yang dikembangkan dalam artikel dipanggil dari Views/ToDo/Index.cshtml file tampilan. Dalam hal berikut, InvokeAsync metode ini dipanggil dengan dua parameter:

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

Memanggil komponen tampilan sebagai Pembantu Tag

Untuk ASP.NET Core 1.1 dan yang lebih tinggi, Anda dapat memanggil komponen tampilan sebagai Pembantu Tag:

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

Parameter metode dan kelas kasus Pascal untuk Pembantu Tag diterjemahkan ke dalam kasus kebab mereka. Tag Helper untuk memanggil komponen tampilan menggunakan <vc></vc> elemen . Komponen tampilan ditentukan sebagai berikut:

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

Untuk menggunakan komponen tampilan sebagai Pembantu Tag, daftarkan rakitan yang berisi komponen tampilan menggunakan direktif @addTagHelper . Jika komponen tampilan Anda berada dalam rakitan yang disebut MyWebApp, tambahkan direktif berikut ke _ViewImports.cshtml file:

@addTagHelper *, MyWebApp

Anda dapat mendaftarkan komponen tampilan sebagai Pembantu Tag ke file apa pun yang mereferensikan komponen tampilan. Lihat Mengelola Cakupan Pembantu Tag untuk informasi selengkapnya tentang cara mendaftarkan Pembantu Tag.

Metode yang InvokeAsync digunakan dalam tutorial ini:

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

Di markup Pembantu Tag:

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

Dalam sampel di atas, PriorityList komponen tampilan menjadi priority-list. Parameter untuk komponen tampilan diteruskan sebagai atribut dalam kasus kebab.

Memanggil komponen tampilan langsung dari pengontrol

Komponen tampilan biasanya dipanggil dari tampilan, tetapi Anda dapat memanggilnya langsung dari metode pengontrol. Meskipun komponen tampilan tidak menentukan titik akhir seperti pengontrol, Anda dapat dengan mudah menerapkan tindakan pengontrol yang mengembalikan konten .ViewComponentResult

Dalam contoh ini, komponen tampilan dipanggil langsung dari pengontrol:

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

Panduan: Membuat komponen tampilan sederhana

Unduh, bangun, dan uji kode pemula. Ini adalah proyek sederhana dengan ToDo pengontrol yang menampilkan daftar item ToDo .

List of ToDos

Menambahkan kelas ViewComponent

Buat folder ViewComponents dan tambahkan kelas berikut PriorityListViewComponent :

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

Catatan tentang kode:

  • Melihat kelas komponen dapat dimuat dalam folder apa pun dalam proyek.

  • Karena nama kelas PriorityListViewComponent diakhiri dengan akhiran ViewComponent, runtime menggunakan string PriorityList saat mereferensikan komponen kelas dari tampilan.

  • Atribut [ViewComponent] dapat mengubah nama yang digunakan untuk mereferensikan komponen tampilan. Misalnya, kelas dapat dinamai XYZViewComponent dengan atribut :

    [ViewComponent(Name = "PriorityList")]
       public class XYZ : ViewComponent
    
  • Atribut [ViewComponent] dalam kode sebelumnya memberi tahu pemilih komponen tampilan untuk digunakan:

    • Nama PriorityList saat mencari tampilan yang terkait dengan komponen
    • String "PriorityList" saat mereferensikan komponen kelas dari tampilan.
  • Komponen menggunakan injeksi dependensi untuk membuat konteks data tersedia.

  • InvokeAsync mengekspos metode yang dapat dipanggil dari tampilan, dan dapat mengambil jumlah argumen yang segan-segan.

  • Metode mengembalikan InvokeAsync sekumpulan ToDo item yang memenuhi isDone parameter dan maxPriority .

Membuat tampilan komponen Razor tampilan

  • Buat folder Views/Shared/Components. Folder ini harus diberi nama Components.

  • Buat folder Views/Shared/Components/PriorityList. Nama folder ini harus cocok dengan nama kelas komponen tampilan, atau nama kelas dikurangi akhiran (jika kita mengikuti konvensi dan menggunakan akhiran ViewComponent dalam nama kelas). Jika Anda menggunakan ViewComponent atribut , nama kelas harus cocok dengan penunjukan atribut.

  • Membuat Views/Shared/Components/PriorityList/Default.cshtmlRazor tampilan:

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

    Tampilan Razor mengambil daftar TodoItem dan menampilkannya. Jika metode komponen InvokeAsync tampilan tidak meneruskan nama tampilan (seperti dalam sampel kami), Default digunakan untuk nama tampilan menurut konvensi. Nanti dalam tutorial, saya akan menunjukkan kepada Anda cara meneruskan nama tampilan. Untuk mengganti gaya default untuk pengontrol tertentu, tambahkan tampilan ke folder tampilan khusus pengontrol (misalnya Views/ToDo/Components/PriorityList/Default.cshtml).

    Jika komponen tampilan khusus pengontrol, Anda dapat menambahkannya ke folder khusus pengontrol (Views/ToDo/Components/PriorityList/Default.cshtml).

  • Tambahkan panggilan yang div berisi ke komponen daftar prioritas ke bagian Views/ToDo/index.cshtml bawah file:

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

Markup @await Component.InvokeAsync menunjukkan sintaks untuk memanggil komponen tampilan. Argumen pertama adalah nama komponen yang ingin kita panggil atau panggil. Parameter berikutnya diteruskan ke komponen. InvokeAsync dapat mengambil jumlah argumen arbitrer.

Menguji aplikasi. Gambar berikut menunjukkan daftar ToDo dan item prioritas:

todo list and priority items

Anda juga dapat memanggil komponen tampilan langsung dari pengontrol:

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

priority items from IndexVC action

Menentukan nama tampilan

Komponen tampilan kompleks mungkin perlu menentukan tampilan non-default dalam beberapa kondisi. Kode berikut menunjukkan cara menentukan tampilan "PVC" dari InvokeAsync metode . InvokeAsync Perbarui metode di PriorityListViewComponent kelas .

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 Salin file ke tampilan bernama Views/Shared/Components/PriorityList/PVC.cshtml. Tambahkan judul untuk menunjukkan tampilan PVC sedang digunakan.

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

Perbarui Views/ToDo/Index.cshtml:

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

Jalankan aplikasi dan verifikasi tampilan PVC.

Priority View Component

Jika tampilan PVC tidak dirender, verifikasi bahwa Anda memanggil komponen tampilan dengan prioritas 4 atau lebih tinggi.

Memeriksa jalur tampilan

  • Ubah parameter prioritas menjadi tiga atau kurang sehingga tampilan prioritas tidak dikembalikan.

  • Ganti nama untuk 1Default.cshtmlsementara menjadi Views/ToDo/Components/PriorityList/Default.cshtml .

  • Uji aplikasi, Anda akan mendapatkan kesalahan berikut:

    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
    
  • Salin Views/ToDo/Components/PriorityList/1Default.cshtml ke Views/Shared/Components/PriorityList/Default.cshtml.

  • Tambahkan beberapa markup ke tampilan komponen tampilan ToDo Bersama untuk menunjukkan tampilan berasal dari folder Bersama .

  • Uji tampilan Komponen bersama.

ToDo output with Shared component view

Menghindari string yang dikodekan secara permanen

Jika Anda ingin mengkompilasi keamanan waktu, Anda dapat mengganti nama komponen tampilan yang dikodekan secara permanen dengan nama kelas. Buat komponen tampilan tanpa akhiran "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 Tambahkan pernyataan ke file tampilan AndaRazor, dan gunakan nameof operator:

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

Anda dapat menggunakan kelebihan metode Component.InvokeAsync yang mengambil jenis CLR. Ingatlah untuk menggunakan typeof operator dalam hal ini:

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

Melakukan pekerjaan sinkron

Kerangka kerja menangani pemanggilan metode sinkron Invoke jika Anda tidak perlu melakukan pekerjaan asinkron. Metode berikut membuat komponen tampilan sinkron Invoke :

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

File komponen Razor tampilan mencantumkan string yang diteruskan ke Invoke metode (Views/Home/Components/PriorityList/Default.cshtml):

@model List<string>

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

Komponen tampilan dipanggil dalam Razor file (misalnya, Views/Home/Index.cshtml) menggunakan salah satu pendekatan berikut:

Untuk menggunakan IViewComponentHelper pendekatan, panggil Component.InvokeAsync:

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

Untuk menggunakan Pembantu Tag, daftarkan rakitan yang berisi Komponen Tampilan menggunakan @addTagHelper direktif (komponen tampilan berada dalam rakitan yang disebut MyWebApp):

@addTagHelper *, MyWebApp

Gunakan Komponen tampilan Tag Helper dalam Razor file markup:

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

Tanda tangan PriorityList.Invoke metode sinkron, tetapi Razor menemukan dan memanggil metode dengan Component.InvokeAsync dalam file markup.

Semua parameter komponen tampilan diperlukan

Setiap parameter dalam komponen tampilan adalah atribut yang diperlukan. Lihat masalah GitHub ini. Jika ada parameter yang dihilangkan:

  • Tanda InvokeAsync tangan metode tidak akan cocok, oleh karena itu metode tidak akan dijalankan.
  • ViewComponent tidak akan merender markup apa pun.
  • Tidak ada kesalahan yang akan dilemparkan.

Sumber Daya Tambahan: