ASP.NET Core Razor Pages 2.2-如何实现共享的ViewComponent

时间:2018-10-17 15:51:07

标签: asp.net asp.net-core razor-pages view-components

我正在使用Razor Pages而不是MVC在ASP.NET Core网站上工作。

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

该组件应由两部分组成:

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

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

我对此有一些疑问。

正如我已经提到的,只需添加以下标记,即可使用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重新呈现。

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

  1. ViewComponent显示必要的标记
  2. 用于发送客户点击次数帖子的JavaScript代码
  3. 伪造PageModel来处理帖子。

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

谢谢。

1 个答案:

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