如何在帖子视图上编辑帖子回复,而无需在单独的视图中执行该操作 [英] How to edit Post Reply on Post View without doing that in a separate View
问题描述
我正在创建一个论坛。这是一个ASP.NET Core 3.1 MVC应用程序。
在帖子索引视图中,帖子标题和内容位于顶部,帖子回复列在下面,并带有Foreach循环。我希望在同一视图上实现编辑功能,而不必创建新的单独视图。
我已经为帖子构建了编辑功能。当用户点击帖子上的编辑按钮时,EditPostModal
会弹出,它就像一个护身符一样起作用。这对我来说是一项相当容易的任务,因为一个帖子视图只有一个对应的帖子。
现在我想为每个回复做一些类似的事情。我现在的问题是,如果我将用于编辑回复的新模式窗口放在用于显示回复的同一Foreach循环中,我将能够访问用于填充模式信息的所有相关属性,但这会造成混乱。首先,我认为每个回复都有一个模式是有点不合适的。此外,现在每个模式实际上都是相同的模式,但具有不同的信息(不同的隐藏ID和内容),当我单击提交按钮时,会发生@reply.Id
的空异常,我认为这是因为它试图同时将来自所有模式的信息传递给困惑的控制器。
请找到下面的代码(简化代码,仅包含相关部分)。
查看模型:
public class PostIndexModel
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime CreatedOn { get; set; }
public string PostContent { get; set; }
public IEnumerable<PostReplyModel> Replies { get; set; }
}
public class PostReplyModel
{
public int Id { get; set; }
public DateTime CreatedOn { get; set; }
public string ReplyContent { get; set; }
}
POST VIEW Index.cshtml:
@model WebProjectAircraftForum.Models.Post.PostIndexModel
<div class="container">
<div class="row PostIndex-PostContent">
<div class="PostContent-Container">
<div class="PostContent-Header">
@Model.CreatedOn
</div>
<div class="PostContent-Text">
@Html.Raw(Model.PostContent)
</div>
<div class="PostContent-Footer">
@if (User.Identity.Name == Model.AuthorName || User.IsInRole("Admin"))
{
<a class="ClassicButton Button-EditPost" data-target="#modalEditPost" onclick="toggleModalPost()">
Edit
</a>
}
</div>
</div>
</div>
foreach (var reply in Model.Replies)
{
<div class="row PostIndex-ReplyContent">
<div ReplyContent-Container">
<div class="PostContent-Header">
@reply.CreatedOn
</div>
<div class="PostContent-Text">
@Html.Raw(reply.ReplyContent)
</div>
<div class="PostContent-Footer">
@if (User.Identity.Name == Model.AuthorName || User.IsInRole("Admin")) //added
{
<a class="ClassicButton Button-EditPost" data-target="#modalEditPost" onclick="toggleModalPostReply()">
Edit
</a>
}
</div>
</div>
</div>
//modal for edit PostReply
<div class="modal fade" id="modalEditPostReply" tabindex="-1" role="dialog" aria-labelledby="modalEditPostReply" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="EditPostFormHeader">
Edit Post Reply
</div>
<form id="EditPostForm1" class="EditPostForm" asp-controller="Post" asp-action="EditReply" method="post">
<input asp-for="@reply.Id" type="hidden" />
<div class="EditPostTextarea">
<textarea rows="10" asp-for="@reply.ReplyContent" required></textarea>
<label asp-for="@reply.ReplyContent"></label>
<span asp-validation-for="@reply.ReplyContent" class="text-danger"></span>
</div>
<div class="CreatePostButtonRow">
<input type="submit" value="edit reply" />
</div>
</form>
</div>
</div>
</div>
</div>
负责接受此消息的PostController
部分:
[Authorize]
[HttpPost]
public async Task<IActionResult> EditReply(PostReplyModel model)
{
var reply = _postService.GetReplyById(model.Id);
await _postService.EditPostReplyContent(reply.Id, model.ReplyContent);
return RedirectToAction("Index", new { id = model.PostId });
}
你能帮忙吗?有没有办法把这个模式从循环中去掉,同时仍然能够这样做?提前谢谢。
推荐答案
使用循环的第一种方式
查看(Index.cshtml):
1.您没有共享toggleModalPost
和toggleModalPostReply
js函数。实际上,不需要使用任何js函数来弹出模式。仅使用默认引导属性data-toggle="modal"
。2.您的模式ID是modalEditPostReply
,但锚中data-target
的值与它不匹配。此外,所有的模式都应该拥有唯一的ID。您需要添加索引以使其唯一。
@model PostIndexModel
@{ int i = 0;} <!--add here -->
<div class="container">
<div class="row PostIndex-PostContent">
<div class="PostContent-Container">
<div class="PostContent-Header">
@Model.CreatedOn
</div>
<div class="PostContent-Text">
@Html.Raw(Model.PostContent)
</div>
<div class="PostContent-Footer"> <!--Not sure which modal does this edit button launch-->
<a class="ClassicButton Button-EditPost" data-toggle="modal" data-target="#modalEditPost_@i">
EditPost
</a>
</div>
</div>
</div>
@foreach (var reply in Model.Replies)
{
<div class="row PostIndex-ReplyContent">
<div ReplyContent-Container">
<div class="PostContent-Header">
@reply.CreatedOn
</div>
<div class="PostContent-Text">
@Html.Raw(reply.ReplyContent)
</div>
<div class="PostContent-Footer"> <!--add data-toggle and change data-target -->
<a class="ClassicButton Button-EditPost" data-toggle="modal" data-target="#modalEditPostReply_@i" >
EditReply
</a>
</div>
</div>
</div>
//modal for edit PostReply
//modify the id....
<div class="modal fade" id="modalEditPostReply_@i" tabindex="-1" role="dialog" aria-labelledby="modalEditPostReply" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="EditPostFormHeader">
Edit Post Reply
</div>
<form id="EditPostForm1" class="EditPostForm" asp-controller="Post" asp-action="EditReply" method="post">
<input asp-for="@reply.Id" type="hidden" />
<div class="EditPostTextarea">
<textarea rows="10" asp-for="@reply.ReplyContent" required></textarea>
<label asp-for="@reply.ReplyContent"></label>
<span asp-validation-for="@reply.ReplyContent" class="text-danger"></span>
</div>
<div class="CreatePostButtonRow">
<input type="submit" value="edit reply" />
</div>
</form>
</div>
</div>
</div>
i++; //add here...
}
</div>
控制器:
您的前端使用asp-for="@reply.PropertyName"
,它将生成name="reply.PropertyName"
,您需要具体的前缀。
[HttpPost]
public async Task<IActionResult> EditReply([Bind(Prefix ="reply")]PostReplyModel model)
{
return RedirectToAction("Index");
}
避免循环的第二种方法
您可以使用分部视图重用模式。
查看(Index.cshtml):
现在您可以使用js函数调用AJAX来加载部分视图,这可以避免循环模式。
@model PostIndexModel
<div class="container">
<div class="row PostIndex-PostContent">
<div class="PostContent-Container">
<div class="PostContent-Header">
@Model.CreatedOn
</div>
<div class="PostContent-Text">
@Html.Raw(Model.PostContent)
</div>
<div class="PostContent-Footer">
<a class="ClassicButton Button-EditPost" data-target="#modalEditPost">
EditPost
</a>
</div>
</div>
</div>
@foreach (var reply in Model.Replies)
{
<div class="row PostIndex-ReplyContent">
<div ReplyContent-Container">
<div class="PostContent-Header">
@reply.CreatedOn
</div>
<div class="PostContent-Text">
@Html.Raw(reply.ReplyContent)
</div>
<div class="PostContent-Footer">
<a class="ClassicButton Button-EditPost" data-target="#modalEditPostReply"
onclick="toggleModalPostReply('@reply.Id')">
EditReply
</a>
</div>
</div>
</div>
<div id="loadModal">
<!--load the modal-->
</div>
}
</div>
@section Scripts
{
<script>
function toggleModalPostReply(id) {
$.ajax({
type: "Get",
url: "/Post/LoadPartial?id="+id,
success: function (data) {
$("#loadModal").html(data);
$('#modalEditPostReply').modal('show')
}
})
}
</script>
}
部分视图(_Partial.cshtml位于视图/共享文件夹中):
@model PostReplyModel
<div class="modal fade" id="modalEditPostReply" tabindex="-1" role="dialog" aria-labelledby="modalEditPostReply" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="EditPostFormHeader">
Edit Post Reply
</div>
<form id="EditPostForm1" class="EditPostForm" asp-controller="Post" asp-action="EditReply" method="post">
<input asp-for="Id" type="hidden" />
<div class="EditPostTextarea">
<textarea rows="10" asp-for="ReplyContent" required></textarea>
<label asp-for="ReplyContent"></label>
<span asp-validation-for="ReplyContent" class="text-danger"></span>
</div>
<div class="CreatePostButtonRow">
<input type="submit" value="edit reply" />
</div>
</form>
</div>
</div>
</div>
控制器:
public IActionResult LoadPartial(int id)
{
var data = _context.Replies.Where(i => i.Id == id).FirstOrDefault();
return PartialView("_Partial", data);
}
[HttpPost]
public async Task<IActionResult> EditReply(PostReplyModel model)
{
return RedirectToAction("Index");
}
这篇关于如何在帖子视图上编辑帖子回复,而无需在单独的视图中执行该操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!