ASP.NET Core Razor Pages 2.2 - Как реализовать общий ViewComponent - PullRequest
0 голосов
/ 17 октября 2018

Я работаю на веб-сайте ASP.NET Core, используя Razor Pages вместо MVC.

Я столкнулся с ситуацией, когда мне нужно реализовать общий компонент, который можно использовать на разных страницах.Компонент - Простая ветка комментариев.На разных страницах подписанные пользователи могут отправлять свои комментарии.

Компонент должен состоять из 2 частей:

  1. Список комментариев - это список комментариев, который может быть легко реализован с помощью любого ViewComponentили частичная страница;
  2. Добавить элемент управления комментарием - это текстовая область и кнопка отправки, которые позволяют пользователю отправлять свой собственный комментарий.

Чего я хочу добиться, так это использовать ViewComponent или частичную страницуили какой-либо другой метод размещения некоторой разметки с начальными параметрами на любой странице, чтобы включить эту функцию комментариев без копирования / вставки одного и того же кода со страницы на страницу.

И у меня есть несколько проблем с этим.

Как я уже упоминал, ViewComponent можно использовать для отображения списка комментариев на любой странице, просто добавив следующую разметку:

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

Таким образом, CommentsViewComponent вызовет ef.core DBContext для загрузки комментариев для определенного типа иЯ бы.Это работает отлично.Но проблема начинает возникать, когда мне нужно отправить сообщения из разметки ViewComponent и обработать эти сообщения.

Планируется сделать 3 возможных почтовых звонка:

  1. Добавить новый комментарий
  2. Удалить существующий комментарий
  3. Редактировать существующий комментарий

Первый возможный подход - определить 3 обработчика на странице NewsItem и вызвать их, используя tag-helper из ViewComponent.Но тогда мне нужно было бы определить 3 одинаковых обработчика на любой другой странице, где мне понадобятся те же функции.

Другой подход, о котором я думал, - определить поддельный PageModel, который будет содержать эти 3 обработчика, и ViewComponent будетразместить на этой странице, используя Ajax.Единственное осложнение заключается в том, что после выполнения этих сообщений мне нужно заставить ViewComponent перерисовывать себя, поскольку комментарии были изменены (удалены, добавлены или отредактированы).

Таким образом, в результате компонент будет содержать следующие части:

  1. ViewComponent для отображения необходимой разметки
  2. JavaScript-код для отправки сообщений по кликам клиентов
  3. Поддельные PageModel для обработки сообщений.

ДонМне не нравится такой подход, и я думаю, что он слишком сложен для такой простой задачи.Это мой первый проект Razor Pages для ядра APS.NET, поэтому у меня нет большого опыта по реализации таких изолированных компонентов, и я надеюсь, что вы, ребята, поможете мне понять, как это можно реализовать, чтобы лучше следовать принципам SOLID и DRY.

Спасибо.

1 Ответ

0 голосов
/ 18 октября 2018

У вас может быть два ViewComponents: один - CommentsViewComponent, который показывает список предыдущих комментариев, и вы можете редактировать / удалять комментарии. Другой - PostCommentViewComponent, к которому вы можете добавить новый комментарий. Например:

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

Прежде всего, вы можете добавить страницы создания / редактирования / удаления бритвы в папку Pages / Comments с соответствующим обработчиком.

Затем, в PostCommentViewComponent, вы можете использовать форму submit для обработчика 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 показать все комментарии и разрешить пользователю перенаправлять на страницы бритвы для редактирования / удаления и перенаправлять назад.

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

...