我正在使用Razor Pages而不是MVC在ASP.NET Core网站上工作。
我遇到了必须实现一个可以在不同页面中使用的共享组件的情况。该组件是-简单注释线程。签名的用户可以在不同的页面上发送他们的评论。
该组件应由两部分组成:
我想要实现的是使用ViewComponent或Partial页面或其他某种技术在任何页面上放置带有初始参数的标记,以启用此注释功能,而无需在页面之间复制/粘贴相同的代码。
我对此有一些疑问。
正如我已经提到的,只需添加以下标记,即可使用ViewComponent在任何页面上显示评论列表:
@await Component.InvokeAsync("Comments", new { type="NewsItem", id="@Model.Item.ID" })
因此,CommentsViewComponent将调用ef.core DBContext来加载已定义类型和ID的注释。这很完美。但是当我需要从ViewComponent的标记发送帖子并处理这些帖子时,问题就开始发生了。
计划有3个可能的帖子通话:
第一种可能的方法是在NewsItem页面上定义3个处理程序,并使用ViewComponent中的tag-helper对其进行调用。但是随后,我将不得不在需要相同功能的任何其他页面上定义3个相同的处理程序。
我正在考虑的另一种方法是定义一些伪造的PageModel,其中将包含这3个处理程序,而ViewComponent将使用Ajax发布到此页面。唯一的麻烦是,做完这些帖子后,由于注释已更改(删除,添加或编辑),我需要强制ViewComponent重新呈现。
因此,该组件将包含以下部分:
我不太喜欢这种方法,对于这样一个简单的任务,它太复杂了。这是我的第一个APS.NET核心Razor Pages项目,所以我对如何实现这样的隔离组件没有太多的经验,希望你们能指导我如何更好地实现这一点,以遵循SOLID和DRY原则。
谢谢。
答案 0 :(得分:0)
您可能有两个ViewComponents:一个是CommentsViewComponent
,它显示以前的评论列表,您可以编辑/删除评论;另一个是PostCommentViewComponent
,您可以添加新评论,例如:
@await Component.InvokeAsync("Comments")
@await Component.InvokeAsync("PostComment")
首先,您可以在Pages / Comments文件夹中添加带有相应处理程序的Create / Edit / Delete剃刀页面。
然后,在PostCommentViewComponent中,您可以使用将表单提交到OnPostCreateAsync处理程序并重定向回去。
public async Task<IViewComponentResult> InvokeAsync()
{
var comment = new Comment();
return View(comment);
}
//Default.cshtml
@model Razor.Models.Comment
<div class="row">
<div class="col-md-4">
<form asp-page="./Comments/Create" asp-page-handler="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Content" class="control-label"></label>
<input asp-for="Content" class="form-control" />
<span asp-validation-for="Content" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
//handler
public async Task<IActionResult> OnPostCreateAsync()
{
//create code
await _context.SaveChangesAsync();
return Redirect(Request.Headers["Referer"].ToString());
}
在CommentsViewComponent中,显示所有注释,并使用户能够重定向到剃须刀页面以进行编辑/删除和redirect返回。
@model IEnumerable<Razor.Models.Comment>
<h4> Comment List</h4>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Content)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Content)
</td>
<td>
<a asp-page="./Comments/Edit" asp-route-id="@item.CommentId">Edit</a> |
<a asp-page="./Comments/Delete" asp-route-
id="@item.CommentId">Delete</a>
</td>
</tr>
}
</tbody>