【问题标题】:How to retain Select value after ajax within a partial view?如何在局部视图中保留 ajax 后的 Select 值?
【发布时间】: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 后重新加载部分时,它都会重置为“选择”。

这也带来了另一个问题,其中,当我通过单击 RUNProcessing 视图上提交表单时,页面将刷新并进入该过程的下一步,但理想情况下也应该发生的是保留部分,再次运行查询,用户不需要在任何时候选择新值,除非他们想运行不同的 SP 来查看表中的不同数据。

这甚至可能吗,还是我试图以完全错误的方式做到这一点?

【问题讨论】:

  • 最烦人的事情是,从各方面来说,这应该是有效的。我从这篇文章中排除了几个日志语句,以减少 cmets 并保持代码的相关性,但是当我在 Chrome 中按 F12 以查看发生了什么时,我会看到所有我希望看到的内容。 OnChange 正在正确记录所选选项,InnerHTML 正在按预期进行适当更改,但此选择只是让我在这里循环。

标签: javascript jquery asp.net-core asp.net-core-mvc


【解决方案1】:

对于您的问题,您可能需要将选定的SprocName 从父视图传递到带有Model 的部分视图。

  1. SelectedSprocName 添加到FeedbackQueries

    public class FeedbackQueries
    {
        public string SelectedSprocName { get; set; }
        public List<FeedbackQuery> Queries { get; set; }
        public FeedbackQueryResults FeedbackQueryResults { get; set; }
    }
    
  2. 改变视图设置SelectedSprocName

    function showFeedbackPartial(x, y, z, q) {
        $.ajax({
            cache: false,
            url: '@Url.Action("GetFeedbackQueryDatatable", "Process")',
            type: 'POST',
            success: function (result) {
                var selected = $('#StoredProcs').val();                   
                model.SelectedSprocName = selected;
                var url = '@Url.Action("ViewFeedbackQueryPartial", "Process")';
                $("#feedbackQueryResultPartial").load(url,{ databaseConnectionString, storedProcedure, page, model });
                console.log('after load' + selected);
               // your rest code
            }
        });
    }
    
  3. 局部视图设置选择选项

    @foreach (FeedbackQuery query in Model.Queries)
    {
        if (query.SprocName == Model.SelectedSprocName)
        {
            @Html.Raw($"<option value='{query.SprocName}' selected='true'>{query.SprocName}</option>");
        }
        else
        {
            @Html.Raw($"<option value='{query.SprocName}'>{query.SprocName}</option>");
        }
    }
    

【讨论】:

  • 非常感谢!我非常接近于弄清楚我所缺少的只是 if 语句。只是为了快速说明您的答案,由于处理视图和部分具有单独的模型,我必须从在 ajax 函数中调用的控制器操作中分配部分模型 (FeedbackQueries) 的值。不过,一旦我得到了分配,您在部分视图中的条件检查就像一个魅力,并保留了回发的价值。
猜你喜欢
  • 2018-09-21
  • 2020-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多