【发布时间】:2020-01-24 20:04:05
【问题描述】:
在我的 ASP.NET Core Web 应用程序中,我有一个局部视图,需要将其放置在多个视图中,并且能够响应动态数据,这些数据会根据当时呈现此局部视图的视图而变化。图片中的红色框表示局部渲染的区域。
partial 本质上是一个Select,它将调用存储过程并返回一个数据表并将该表呈现给局部视图。我可以在页面上选择一个选项并让它调用 SP 并查看数据表中的所有相关数据,并且可以将其写在页面上没问题。我遇到的问题是,每次通过 ajax 进行部分刷新时,Select 都会返回默认的“选择”值,并且不会保持先前选择的选项处于选中状态。
为简洁起见,假设FeedbackQueries 对象只包含4 个字符串元素。
_FeedbackQueryResultPartial.cshtml
@using Contract.Shared;
@model FeedbackQueries
<style>
#select {
margin: auto;
text-align: center;
}
</style>
<div id="feedbackQueryResultPartial">
<div style="height:25px;">
<div id="select">
<select name="StoredProcs" id="StoredProcs" onchange="selectQuery()">
<option value="Select">Select</option>
@foreach (FeedbackQuery query in Model.Queries)
{
@Html.Raw($"<option value='{query.SprocName}'>{query.SprocName}</option>");
}
</select>
</div>
<div id="feedbackQueryDiv" class="row">
@if (Model.FeedbackQueryResults.Rows.Count > 0)
{
<h3>DataTable goes here</h3>
}
else
{
<h3>No rows were returned from your query. Please select another.</h3>
}
</div>
</div>
</div>
Processing.cshtml
@using Contract.Parent
@using Contract.Shared
@model Processing
<script>
function showFeedbackPartial(x, y, z, q) {
$.ajax({
cache: false,
url: '@Url.Action("GetFeedbackQueryDatatable", "Client")',
type: 'POST',
data: { databaseConnectionString: x, storedProcedure: y, page: z, Model: q },
success: function (result) {
var selected = $('#StoredProcs').val();
console.log(selected);
if (result.rowCount > 0) {
console.log(result.rowCount);
var databaseConnectionString = x;
var storedProcedure = y;
var page = z;
var model = q;
var url = '@Url.Action("ViewFeedbackQueryPartial", "Client")';
$("#feedbackQueryResultPartial").load(url, { databaseConnectionString, storedProcedure, page, model });
}
else {
document.getElementById('feedbackQueryDiv').innerHTML = '<h3>No rows were returned from your query. Please select another.</h3>';
}
$('#StoredProcs').val(selected);
$("#StoredProcs option[value='Select']").remove();
}
});
}
</script>
<script>
function selectQuery() {
var e = document.getElementById('StoredProcs');
var ev = e.options[e.selectedIndex].text;
var p = 'Processing';
var model = @Html.Raw(Json.Serialize(Model.FeedbackQueries));
console.log(model);
showFeedbackPartial('@Model.Client.DatabaseConnectionString', ev, p, model);
}
</script>
<script>
$(document).ready(function () {
document.getElementById('feedbackQueryDiv').innerHTML = '<h3>Select a query to view feedback.</h3>';
});
</script>
}
<form method="post" enctype="multipart/form-data">
...
<partial name="_FeedbackQueryResultPartial" for="@Model.FeedbackQueries" />
...
</form>
呈现处理视图的控制器操作
[HttpGet]
public IActionResult Processing(int Id)
{
ViewBag.Id = Id;
Processing processing = new Processing();
//Get pertinent information for Client
processing.Client = _clientProcessingService.GetSingleClient(Id, _appSettings.MOPConfigConnectionString);
processing.Client.DatabaseConnectionString = _clientProcessingService.GetClientConnectionFromConfig(processing.Client, _appSettings);
processing.Steps = _clientProcessingService.GetClientSteps(processing.Client.DatabaseConnectionString, "Processing");
processing.CurrMoInfo.CurrMo = _clientProcessingService.GetProcessingCurrMo(processing.Client.DatabaseConnectionString);
processing.FeedbackQueries = _clientProcessingService.GetFeedbackQueriesFromDb(processing.Client.DatabaseConnectionString, "Processing");
return View(processing);
}
[HttpPost]
public IActionResult Processing(Processing Model)
{
//Get pertinent information for Client
Model.Client = _clientProcessingService.GetSingleClient(Model.Client.ClientID, _appSettings.MOPConfigConnectionString);
Model.Client.DatabaseConnectionString = _clientProcessingService.GetClientConnectionFromConfig(Model.Client, _appSettings);
Model.Steps = _clientProcessingService.GetClientSteps(Model.Client.DatabaseConnectionString, "Processing");
Model.CurrMoInfo.CurrMo = _clientProcessingService.GetProcessingCurrMo(Model.Client.DatabaseConnectionString);
Model.FeedbackQueries = _clientProcessingService.GetFeedbackQueriesFromDb(Model.Client.DatabaseConnectionString, "Processing");
return View(Model);
}
呈现部分的控制器动作
public IActionResult ViewFeedbackQueryPartial(string DatabaseConnectionString, string StoredProcedure, string Page, FeedbackQueries Model)
{
if(StoredProcedure == "Select")
{
return PartialView("_FeedbackQueryResultPartial", Model);
}
Model.FeedbackQueryResults = _clientProcessingService.GetFeedbackQueryDataTable(DatabaseConnectionString, Page, StoredProcedure);
return PartialView("_FeedbackQueryResultPartial", Model);
}
我尝试了很多不同的方法来保持这个价值。将其添加到模型中,将其添加到 Viewbag 以及无数其他尝试在某处保留此值的方法,无论成功或失败,保留该值并通过 javascript 将其更改为选定的选项。每次调用 ajax 后重新加载部分时,它都会重置为“选择”。
这也带来了另一个问题,其中,当我通过单击 RUN 在 Processing 视图上提交表单时,页面将刷新并进入该过程的下一步,但理想情况下也应该发生的是保留部分,再次运行查询,用户不需要在任何时候选择新值,除非他们想运行不同的 SP 来查看表中的不同数据。
这甚至可能吗,还是我试图以完全错误的方式做到这一点?
【问题讨论】:
-
最烦人的事情是,从各方面来说,这应该是有效的。我从这篇文章中排除了几个日志语句,以减少 cmets 并保持代码的相关性,但是当我在 Chrome 中按 F12 以查看发生了什么时,我会看到所有我希望看到的内容。
OnChange正在正确记录所选选项,InnerHTML正在按预期进行适当更改,但此选择只是让我在这里循环。
标签: javascript jquery asp.net-core asp.net-core-mvc