Del*_*vor 5 c# asp.net-core-mvc asp.net-core
我正在为侧边栏创建部分视图,以显示我网站中最受欢迎的帖子.如何创建用于加载局部视图所需模型的独立控制器?(IEnumerable<Post>随着热门帖子)
目前我已经创建了一个加载流行帖子的控制器类,但是在渲染部分时我一直遇到错误,因为我无法调用控制器并加载部分模型.例如,如果我从我呈现单个帖子的视图中调用它,则模型类型将不匹配(Postvs IEnumerable<Post>)
这是我的SidebarController:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using GoBaron.Front.Models;
namespace GoBaron.Front.Controllers
{
public class SidebarController : Controller
{
private readonly ApplicationDbContext _context;
public SidebarController(ApplicationDbContext context)
{
_context = context;
}
public async Task<IActionResult> PopularPosts()
{
return PartialView(await _context.Posts
.Where(p => p.IsActive == true)
.OrderByDescending(p => p.Id)
.Take(5)
.ToListAsync());
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的部分观点PopularPosts.cshtml:
@model IEnumerable<GoBaron.Front.Models.Post>
@using GoBaron.Front.Data.Extensions
@if (Model.Any())
{
<div class="sidebar-item" id="topTrending">
<header class="sidebar-item__header">
<h1>Najpopularniejsze</h1>
</header>
<div class="sidebar-item__content">
@foreach (var item in Model)
{
<a asp-controller="Post" asp-action="Details" asp-route-id="@item.Id" asp-route-slug="@item.Title.ConvertToSlug()" title="@item.Title">
<div class="sidebar-post-item" style="background-image:url('@item.PosterUrl')">
<span class="sidebar-post-item__counter">+5</span>
<span class="sidebar-post-item__title">@item.Title</span>
</div>
</a>
}
</div>
</div>
}
Run Code Online (Sandbox Code Playgroud)
当我想要包含热门帖子侧边栏时,例如在布局中,我只需添加:
@await Html.PartialAsync("~/Views/Sidebar/PopularPosts.cshtml")
Run Code Online (Sandbox Code Playgroud)
Dan*_*.G. 17
这是View Component的一个很好的用例,而不是局部视图.您不仅需要渲染视图,还需要执行从db加载Popular Posts的逻辑.
而不是Controller,创建一个新ViewComponent类.这包含在其InvokeAsync方法中为视图组件准备模型的逻辑,它可以使用任意数量的参数.在你的情况下InvokeAsync没有参数,将从数据库加载流行的帖子,并将呈现视图组件视图:
public class PopularPostsViewComponent: ViewComponent
{
private readonly ApplicationDbContext _context;
public PopularPostsViewComponent(ApplicationDbContext context)
{
_context = context;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var posts = await _context.Posts
.Where(p => p.IsActive == true)
.OrderByDescending(p => p.Id)
.Take(5)
.ToListAsync();
return View(posts);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您需要为该视图组件创建视图.默认视图名称Default.cshtml(如果return View()没有指定视图名称时),它应该位于Views/Shared/Components/PopularPosts/Default.cshtml.这基本上与您当前的局部视图相同:
@model IEnumerable<GoBaron.Front.Models.Post>
@using GoBaron.Front.Data.Extensions
@if (Model.Any())
{
<div class="sidebar-item" id="topTrending">
<header class="sidebar-item__header">
<h1>Najpopularniejsze</h1>
</header>
<div class="sidebar-item__content">
@foreach (var item in Model)
{
<a asp-controller="Post" asp-action="Details" asp-route-id="@item.Id" asp-route-slug="@item.Title.ConvertToSlug()" title="@item.Title">
<div class="sidebar-post-item" style="background-image:url('@item.PosterUrl')">
<span class="sidebar-post-item__counter">+5</span>
<span class="sidebar-post-item__title">@item.Title</span>
</div>
</a>
}
</div>
</div>
}
Run Code Online (Sandbox Code Playgroud)
然后从任何其他视图,您将渲染视图组件而不是部分,传递所需的任何参数InvokeAsync.在你的情况下,你没有参数,所以它将是:
@await Component.InvokeAsync("PopularPosts")
Run Code Online (Sandbox Code Playgroud)
最后,如果您使用的是.Net Core 1.1或更高版本,您还可以将其作为标记帮助程序调用:
<vc:popular-posts></vc:popular-posts>
Run Code Online (Sandbox Code Playgroud)
PS.我写了一篇文章,描述了您可能感兴趣的部分,标记助手和视图组件的用法.
| 归档时间: |
|
| 查看次数: |
15792 次 |
| 最近记录: |