ajax - 如何使用单选按钮单击 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"> </div>
<div class="row">
<div class="col-sm-2"> </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)" })
@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>
解决方案
推荐阅读
- java - RSAPubKey 元素中的模值不匹配
- django - 错误消息“mkvirtualenv 未被识别为内部或外部命令”
- android - Android - 使用数据绑定来分配布局?
- c# - 弹性搜索(使用 NEST)在 MatchAll() 上返回 0 个结果
- r - 无法安装包 'ggpmisc' 不可用(对于 R 版本 3.5.0)
- r - 在 Windows CMD (powershell) 中使用正则表达式从 XML 中删除 CDATA
- labview - 如何通过 Labview 上的热电偶获取温度
- javascript - 在缩短的链接之前添加 URL 的其余部分
- python - 如何设置热图的 X 轴和 Y 轴范围?
- r - 从数据框名称列表创建数据框列表(用于merge_all)