0

我正在使用 Razor Pages 而不是 MVC 开发 ASP.NET Core 网站。

我遇到了一种情况,我必须实现一个可以在不同页面中使用的共享组件。该组件是 - 简单的评论线程。在不同的页面上签名的用户可以发送他们的评论。

该组件应由两部分组成:

  1. 评论列表 - 这是可以使用 ViewComponent 或 Partial Page 轻松实现的评论列表;
  2. 添加评论控制 - 这是文本区域和提交按钮,允许用户发送他们自己的评论。

我想要实现的是使用 ViewComponent 或部分页面或其他一些技术在任何页面上放置一些带有初始参数的标记,以启用此评论功能,而无需在页面之间复制/粘贴相同的代码。

我对此有一些问题。

正如我已经提到的,只需添加以下标记,即可使用 ViewComponent 在任何页面上显示评论列表:

@await Component.InvokeAsync("Comments", new { type="NewsItem", id="@Model.Item.ID" })

所以 CommentsViewComponent 将调用 ef.core DBContext 来加载定义类型和 id 的评论。这很完美。但是当我需要从 ViewComponent 的标记发送帖子并处理这些帖子时,问题就开始发生了。

计划有 3 个可能的邮寄电话:

  1. 添加新评论
  2. 删除现有评论
  3. 编辑现有评论

第一种可能的方法是在 NewsItem 页面上定义 3 个处理程序,并使用 ViewComponent 中的 tag-helper 调用它们。但是我必须在需要相同功能的任何其他页面上定义 3 个相同的处理程序。

我正在考虑的另一种方法是定义一些假的 PageModel 将包含这 3 个处理程序,并且 ViewComponent 将使用 Ajax 发布到该页面。这里唯一的复杂之处是,在完成这些帖子之后,我需要强制 ViewComponent 重新呈现自己,因为 Comments 已更改(删除、添加或编辑)。

因此,该组件将包含以下部分:

  1. ViewComponent 显示必要的标记
  2. 在客户端点击时发送帖子的 JavaScript 代码
  3. 假 PageModel 来处理帖子。

我不太喜欢这种方法,而且我认为对于这样一个简单的任务来说它太复杂了。这是我的第一个 APS.NET 核心 Razor Pages 项目,所以我对如何实现此类隔离组件没有太多经验,希望你们能指导我如何以更好的方式实现它,以遵循 SOLID 和 DRY 原则。

谢谢。

4

1 回答 1

0

您可以有两个 ViewComponents:一个是CommentsViewComponent显示先前评论的列表,您可以编辑/删除评论。另一个是PostCommentViewComponent您可以添加新评论。例如:

@await Component.InvokeAsync("Comments")
@await Component.InvokeAsync("PostComment")

首先,您可以使用相应的处理程序在 Pages/Comments 文件夹中添加创建/编辑/删除剃须刀页面。

然后,在 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 中,显示所有评论并允许用户重定向到 razor 页面进行编辑/删除并重定向回来。

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

于 2018-10-18T07:22:21.167 回答