首页 > 解决方案 > 如何使用单选按钮单击 MVC 触发 Ajax 功能

问题描述

我有一个由 3 个部分视图组成的视图:

Partial View #1 列出 RadioButtons。当我单击一个按钮时,我想将结果选择发送到控制器,以更新 Partial View #2(这是一个 Telerik 网格)。然后 PV #2 中的选择将更新 Partial View #3(另一个 Telerik 网格)。

我目前正在做一个 Window.location 将选定的值发送到 Controller ,这会导致 Controller 和 ViewModel 被重新加载并丢失状态。除了失去状态,流程按我的意愿工作。

有没有办法在 Ajax 中做到这一点,我不必重新加载控制器?

我将为您省去 Telerik 网格的 Partial Views #2 和 #3。如果我能得到如何让单选按钮在没有回发的情况下调用控制器的答案,我可以将同样的方法应用于那些部分视图。

看法:

    @model MyProject.ViewModel.MaterialsListVM
@{
    ViewBag.Title = "Materials List";
}

<div>        
    <div class="row">
        <div class="col-sm-2">
            @Html.Partial("MaterialTypeFilter")
        </div>

        <div class="col-lg-10">
            @Html.Partial("MaterialsGrid")            
        </div>
    </div>
    <div class="row">&nbsp;</div>
    <div class="row">
        <div class="col-sm-2">&nbsp;</div>
        <div class="col-lg-10">
            @Html.Partial("ProjectMaterialsGrid")
        </div>
    </div>
    </div>

部分视图#1:

@model MyProject.ViewModel.MaterialsListVM

<div class="container">
   <h5>   @Html.Label("Material Type:  ", new { style = "font-weight:bold;" })</h5>
            @if (Model != null)
            {
                for (int i = 0; i < Model.Material_Type.MaterialTypeList.Count; i++)
                {
            <span class="btn-group-sm">
                @Html.RadioButton("MatType", new { Model.Material_Type.MaterialTypeList[i].Name }, Model.Material_Type.MaterialTypeList[i].Selected, new { @onclick = "CallChangefunc(this.value)" })
                &nbsp;
                @Html.Label(Model.Material_Type.MaterialTypeList[i].Name)
            </span><br />
                }
            }

     </div>

<script>
        function CallChangefunc(value) {
            var selected = value.replace("{ Name = ", "");
            selected = selected.replace("}", "");

            window.location = '@Url.Action("Index", "MaterialsList")' + '?selectedMatType=' + selected;
            //alert("val is:" + selected);
    }

更新

我将 JavaScript 更改为这个 Ajax 调用并调用了我的 Controller HttpPost Index() 函数:

$(document).ready(function () {
        $(':radio[name="MatType"]').change(function (e) {
            $.ajax({
                type: 'POST',
                url: '/MaterialsList/Index',
                data: { selectedMatType: $(':radio[name="MatType"]:checked').val()},
                dataType: "json",
                success: function (data) {
                    alert('did it');
                }
            });
        });
    })

不幸的是,控制器仍在重新加载,我正在丢失选择到 Partial View #3 Telerik 网格中的数据状态......

...任何帮助将非常感激...

更新#2

这个解决方案很糟糕,但我不知道还能做什么......

目标是在 Partial View #3 中保留 Telerik 网格的数据源状态。数据源是一个带有类对象列表的 ViewModel。

添加了来自 Controller 的 Partial View #2 代码和 ActionResult。没有 HttpPost 索引功能。每个单选按钮更改都会触发 ActionResult 索引。Telerik 网格中的每个选择事件都会触发 ActionResult Index。

相关控制器代码:

public ActionResult Index(string selectedMatType, string selectedMaterials, string projectMaterialsList)      
        {
            if (projectMaterialsList != null)
            {
                materialsListVM.ProjectMaterialsList = JsonConvert.DeserializeObject<List<ProjectMaterialsListVM.ProjectMaterial>>(projectMaterialsList);
            }

            if (selectedMatType != null)
            {
                materialsListVM.SelectMaterialType(selectedMatType);
                materialsListVM.GetMaterials();
            }

            if (selectedMaterials != null)
            {
                string[] materialIds = selectedMaterials.Split(',');
                foreach (string id in materialIds)
                {
                    MoveToProjectMaterialsList(id, selectedMatType);
                }
            }
            ViewBag.ProjectMaterialsList = materialsListVM.ProjectMaterialsList;
            ViewBag.SelectedMatType = selectedMatType;
            return View(materialsListVM);
        }

部分视图#2 代码:

@model MyProject.ViewModel.MaterialsListVM

<div>
    @if (ViewBag.SelectedMatType == "Cap Weld")
    {
        @(Html.Kendo().Grid(Model.CapWeld_Materials)
                            .Name("grid")
                            .Columns(columns =>
                            {
                                columns.Select().Width(40);
                                columns.Bound(c => c.MaterialId).Hidden();
                                columns.Bound(c => c.MaterialTypeName);
                                columns.Bound(c => c.PcsPartNum);
                                columns.Bound(c => c.ClientPartNum);
                                columns.Bound(c => c.Type).Filterable(ftb => ftb.Multi(true));
                                columns.Bound(c => c.OuterDiameter).Filterable(ftb => ftb.Multi(true));
                                columns.Bound(c => c.WallThickness).Filterable(ftb => ftb.Multi(true));
                                columns.Bound(c => c.Specification).Filterable(ftb => ftb.Multi(true));
                                columns.Bound(c => c.Grade).Filterable(ftb => ftb.Multi(true));
                            })
                            .Events(ev => ev.Change("onChange"))
                            .Pageable()
                            .Sortable()
                            .Scrollable()
                            .TableHtmlAttributes(new { width = "100%" })
                            //.HtmlAttributes(new { style="height:500px"})
                            .PersistSelection(true)
                            .Filterable()
                            .DataSource(datasource => datasource
                            .Ajax()
                            .ServerOperation(false)
                            .Model(m => m.Id(d => d.MaterialId))
                            )
        );
    }
</div>

@{
    var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
    var val = jss.Serialize(ViewBag.ProjectMaterialsList);
}


<script>
    function onChange(arg) {
        var selectedMatType = '@(ViewBag.SelectedMatType)';
        var projectMaterialsList = '@Html.Raw(val)';
        //var obj = $.parseJSON(val);
        var grid = $('#grid').data('kendoGrid');
        var selectedMaterials = grid.selectedKeyNames().join(", ");
       // alert(selectedMaterials);
        @*$.ajax({
            type: "POST",
            data: { selectedMatType: selectedMatType, selectedMaterials: selectedMaterials, projectMaterialsList: projectMaterialsList },
            dataType: "json",
            url: @Url.Action("Index", "MaterialsList")
        });*@

        window.location = '@Url.Action("Index", "MaterialsList")' + '?selectedMatType=' + selectedMatType + '&selectedMaterials=' + selectedMaterials
            + '&projectMaterialsList=' + projectMaterialsList;
    }
</script>

标签: ajaxasp.net-mvc-5

解决方案


推荐阅读