当StatusReport变量更新时,如何重新渲染Razor Pages局部视图?
问题描述
这是此前提问的跟进问题:
在Razor Pages中,当StatusReport变量更新后,如何重新渲染页面或局部视图(理想状态为仅渲染局部视图)?
用户从下拉列表选择不同状态时,会发送新的POST请求,更新PartialIndexModel中的StatusReport变量,希望此时局部视图_MyPartial能携带新数据重新渲染。以下是相关代码:
页面代码(PartialIndex.cshtml)
@page @model Demo.Pages.PartialIndex @{ ViewData["Title"] = "Home"; } @Html.AntiForgeryToken() <h1>@Model.StatusReport.Name</h1> <section class="hero-style-2"> <div class="slider"> .... </div> </section> <partial name="_MyPartial" model="@Model.StatusReport" /> @section Scripts{ <script> $("#sel-options").change(function () { var value = $("#sel-options option:selected").val(); var data = { "value": value }; $.ajax({ type: 'Post', beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); }, url: '@Url.Page("PartialIndex","Ajax")', data: data, success: function (data) { // Do something }, error: function (err){ toast.error(err.message); } }) }) </script> }
模型代码(StatusReport.cs)
public class StatusReport { public string Name { get; set; } public Report Report { get; set; } }
局部视图代码(_MyPartial.cshtml)
@using Models.Entities; @model StatusReport @if (Model != null) { <div class="row"> <div class="col-md"> <label class="label-text" for="sel-options">Status</label> </div> <div class="col-md-2"> <select id="sel-options" class="form-control lable-text"> <option selected value="Do">Done</option> <option value="Done">Done</option> <option value="Canceled">Canceled</option> </select> </div> </div> <div> // Render @Model.Report </div> }
PageModel代码(PartialIndex.cs)
namespace Demo.Pages; public class PartialIndexModel : PageModel { [BindProperty] public StatusReport StatusReport { get; set; } = new(); [BindProperty] public string status { get; set; } = "Do"; private readonly IStatusService _statusService; public PartialIndexModel (IStatusService statusService) { _statusService = statusService; } public async Task<IActionResult> OnGet() { StatusReport = await _statusService.GetItemsWithSatus(status); return Page(); } public async Task<IActionResult> OnPostAjax(string value) { StatusReport = await _statusService.GetItemsWithSatus(value); // After StatusReport is updated from the request, I want to be able to re-render the Partial _MyPartial return Page(); } }
解决方案
要实现仅重新渲染局部视图,需修改后端返回逻辑和前端DOM替换逻辑,步骤如下:
1. 修改后端OnPostAjax方法,返回局部视图
当前返回return Page()会输出整个页面,需改为返回指定局部视图并传入更新后的模型:
public async Task<IActionResult> OnPostAjax(string value) { StatusReport = await _statusService.GetItemsWithSatus(value); // 返回局部视图及更新后的模型数据 return Partial("_MyPartial", StatusReport); }
2. 给局部视图加容器标识,方便前端替换
在主页面的<partial>标签外层添加带ID的容器:
<div id="partial-container"> <partial name="_MyPartial" model="@Model.StatusReport" /> </div>
3. 修改前端AJAX回调,替换局部视图内容
更新success回调,用后端返回的局部视图HTML替换容器内容:
success: function (data) { // 用新的局部视图HTML替换原有内容 $("#partial-container").html(data); },
4. 修复下拉框事件绑定(关键)
因为局部视图被重新渲染后,原有下拉框的change事件绑定会失效,需改用事件委托绑定事件:
// 替换原有的$("#sel-options").change(...) $(document).on("change", "#sel-options", function () { var value = $(this).val(); var data = { "value": value }; $.ajax({ type: 'Post', beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); }, url: '@Url.Page("PartialIndex","Ajax")', data: data, success: function (data) { $("#partial-container").html(data); }, error: function (err){ toast.error(err.message); } }) })
内容的提问来源于stack exchange,提问作者Sachihiro
相关产品推荐
相关产品推荐

