728x90
반응형
View Components는 ASP.NET Core MVC에서 새롭게 소개된 feature다. partial view와 비슷하지만, 더 강력하다. View Components는 model binding을 사용하지 않고, 호출 시 제공받은 data만 사용한다. partial view를 사용하기에 로직이 너무 복잡할 때 사용한다. 가장 중요한 것은, dependency injection을 사용한다는 것이다.
- SOC(Separation Of Concerns)를 지원한다.
- parameter와 고유 business logic을 가진다.
- Layer Page에서 실행된다.
- chunk만 렌더링 한다.
- filters는 사용할 수 없다.
- request로 호출할 수 없다. 보통 view에서 호출된다.
View Component 만들기
아래 두 가지 방식으로 View Component를 선언한다. class명은 ViewComponent로 끝난다.
public class EmployeeViewComponent: ViewComponent
{ }
[ViewComponent(Name = "Employee")]
public class EmployeeInfo: ViewComponent
{}
위 class 파일은 Shared폴더에 저장한다.
view component class에서 우리는 한 메서도를 반드시 정의해야 한다.
public async Task InvokeAsync(string EmployeeCode) {
Employee objEmployee;
//...retrieve or build Employee object for a specified Employee
return View(objEmployee);
}
View Component 호출하기
이제 @Component.InvokeAsync()함수를 사용해서 view 어디에서든 view component를 호출할 수 있다.
@Component.InvokeAsync("EmployeeViewComponent",<anonomous type containing params>)
parameter는 InvokeAsync함수로 전달된다.
@await Component.InvokeAsync("EmployeeViewComponent", "A001")
View Components는 보통 views에서 호출되지만, controller에서도 가능하다.
public IActionResult EmployeeView()
{
return ViewComponent("EmployeeViewComponent", "A001");
}
IViewComponentResult, Task<IViewComponentResult>를 반환한다.
간단한 View Component 만들어보기
PriorityListViewComponents.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using VUE.Models;
namespace VUE.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);
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);
}
private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
{
return db.ToDo.Where(x => x.IsDone == isDone &&
x.Priority <= maxPriority).ToListAsync();
}
}
}
Index.cshtml
@using VUE.Models
@model IEnumerable<TodoItem>
@{
Layout = null;
}
<h2>ToDo</h2>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.IsDone)
</th>
<th>
@Html.DisplayNameFor(model => model.Priority)
</th>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.IsDone)
</td>
<td>
@Html.DisplayFor(modelItem => item.Priority)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
</tr>
}
</table>
<div>
@await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
</div>
Default.cshtml
@model IEnumerable<VUE.Models.TodoItem>
<h3>Priority Items</h3>
<ul>
@foreach (var todo in Model)
{
<li>@todo.Name</li>
}
</ul>
PVC.cshtml
@model IEnumerable<VUE.Models.TodoItem>
<h2> PVC Named Priority Component View</h2>
<h4>@ViewBag.PriorityMessage</h4>
<ul>
@foreach (var todo in Model)
{
<li>@todo.Name</li>
}
</ul>
ToDoController.cs
using Microsoft.AspNetCore.Mvc;
using VUE.Models;
namespace VUE.Controllers
{
public class ToDoController : Controller
{
private readonly ToDoContext _ToDoContext;
public ToDoController(ToDoContext context)
{
_ToDoContext = context;
// EnsureCreated() is used to call OnModelCreating for In-Memory databases as migration is not possible
// see: https://github.com/aspnet/EntityFrameworkCore/issues/11666
_ToDoContext.Database.EnsureCreated();
}
public IActionResult Index()
{
var model = _ToDoContext.ToDo.ToList();
return View(model);
}
#region snippet_IndexVC
public IActionResult IndexVC()
{
return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}
#endregion
}
}
ToDoContext.cs
using Microsoft.EntityFrameworkCore;
namespace VUE.Models
{
public class ToDoContext : DbContext
{
public ToDoContext(DbContextOptions<ToDoContext> options)
: base(options)
{
}
public DbSet<TodoItem> ToDo { get; set; }
//The below is used to seeding the DB
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
for (int i = 0; i < 9; i++)
{
modelBuilder.Entity<TodoItem>().HasData(
new TodoItem
{
Id = i + 1,
IsDone = i % 3 == 0,
Name = "Task " + (i + 1),
Priority = i % 5 + 1
});
}
}
}
}
ToDoItem.cs
using System.ComponentModel.DataAnnotations;
namespace VUE.Models
{
public class TodoItem
{
public int Id { get; set; }
public string Name { get; set; }
public int Priority { get; set; }
public bool IsDone { get; set; }
}
}
Program.cs
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<ToDoContext>(options =>
options.UseInMemoryDatabase("db"));
var app = builder.Build();
728x90
반응형
'ASP.NET Core' 카테고리의 다른 글
ASP.NET Core MVC 6] Identity (0) | 2022.01.12 |
---|---|
ASP.NET Core MVC] Routing 라우팅 (0) | 2022.01.11 |
ASP.NET Core MVC] ViewData, [ViewData] attribute, ViewBag (0) | 2022.01.10 |
ASP.NET Core] Model Validation Check (0) | 2021.12.31 |
ASP.NET Core 시작하기! - Core설명, 프로젝트 만들기, 구조 (1) (0) | 2021.12.22 |
댓글