.net - 在 .net-core 中选择 onchange 到 Controller 的 Action
问题描述
我有一个按类型分类的对象列表,所以我的视图上有一个“类型”选择
<form asp-action="Index" asp-route-type=" ? selectedTypeId ? ">
<select asp-items="ViewBag.Types" onchange="this.form.submit()"></select>
</form>
我的控制器的动作是
public async Task<IActionResult> Index([FromQuery(Name = "type")] int type) {
// filter the object list by type
}
如何使用选择正确重新加载视图?
我看到提出了 Ajax 解决方案,这将是一个很好的解决方案,但是我的问题是,当我更改产品类型时,不仅产品列表会更改,而且产品特性(列)也会更改,创建按钮也应该只创建产品类型,因此,它会改变所有视图行为。我宁愿重新加载所有视图而不是其中的一部分。
解决方案
如何使用选择正确地重新加载视图?
看来您想根据 DropDownList 选择的值过滤数据,在我看来,我更喜欢使用 Partial View 来显示过滤后的数据并使用 JQuery Ajax 来更新内容。请参考以下示例:
创建一个 ProductViewModel 视图模型:
public class ProductViewModel
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string ProductType { get; set; }
}
控制器方法:
//ProductIndex Page
public IActionResult ProductIndex()
{
//get all the initial data from the repository
var productlist = _repo.GetProductViewModels();
//set select items for the DropDownList
ViewBag.Types = _repo.GetProductViewModels().Select(c=>c.ProductType).Distinct().ToList().Select(c => new SelectListItem { Text = c, Value = c }).ToList();
return View(productlist);
}
//based on the type filter data and return partial view.
public IActionResult ShowProduct(string type)
{
var productlist = _repo.GetProductViewModels().ToList();
//based on the type to filter data.
if (!string.IsNullOrEmpty(type) && type != "all")
{
productlist = productlist.Where(c => c.ProductType == type).ToList();
}
//required using Microsoft.AspNetCore.Mvc.Rendering;
ViewBag.Types = _repo.GetProductViewModels().Select(c => new SelectListItem { Text = c.ProductType, Value = c.ProductType }).Distinct().ToList();
return PartialView("_ShowProductPartialView", productlist );
}
创建_ShowProductPartialView.cshtml
局部视图以显示产品列表:
@model IEnumerable<netcore5.Models.ProductViewModel>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.ProductId)
</th>
<th>
@Html.DisplayNameFor(model => model.ProductName)
</th>
<th>
@Html.DisplayNameFor(model => model.ProductType)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.ProductId)
</td>
<td>
@Html.DisplayFor(modelItem => item.ProductName)
</td>
<td>
@Html.DisplayFor(modelItem => item.ProductType)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</tbody>
</table>
ProductIndex 页面中的代码:
@model IEnumerable<netcore5.Models.ProductViewModel>
@{
ViewData["Title"] = "ProductIndex";
}
<h1>ProductIndex</h1>
<form asp-action="ProductIndex">
<select id="ddltype" name="type" asp-items="ViewBag.Types" >
<option value="all">All Type</option>
</select>
<div id="productcontainer">
<partial name="_ShowProductPartialView.cshtml" model="@Model" />
</div>
</form>
@section Scripts{
<script>
$(function () {
$("#ddltype").change(function () {
$.ajax({
type: "Get",
url: "/Home/ShowProduct?type=" + $(this).val(), //remember change the controller to your owns.
success: function (data) {
$("#productcontainer").html("");
$("#productcontainer").html(data);
},
error: function (response) {
console.log(response.responseText);
}
});
});
});
</script>
}
然后,结果如下:
【注意】使用上述方法,主页面不会更新,只刷新局部视图。
如果你想使用<select>
元素onchange
事件,你可以Submit
在表单中添加一个按钮,在onchange
事件中,点击Submit
按钮,它会提交表单。然后,您可以根据类型过滤数据。
将上面的代码更改如下: 在 ProductIndex.cshtml 页面中,删除 JQuery 脚本并添加一个提交按钮,为select
元素添加名称属性,然后在 selectonchange
事件中,单击提交按钮:
@model IEnumerable<netcore5.Models.ProductViewModel>
@{
ViewData["Title"] = "ProductIndex";
}
<h1>ProductIndex</h1>
<form asp-action="ProductIndex">
<select id="ddltype" name="type" asp-items="ViewBag.Types" onchange="document.getElementById('btnSubmit').click();" >
<option value="all">All Type</option>
</select>
<div id="productcontainer">
<partial name="_ShowProductPartialView.cshtml" model="@Model" />
</div>
<input id="btnSubmit" hidden type="submit" value="submit" />
</form>
控制器中的代码:
public IActionResult ProductIndex(string type)
{
//get all the initial data from the repository
var productlist = _repo.GetProductViewModels();
//based on the type to filter data.
if (!string.IsNullOrEmpty(type) && type != "all")
{
productlist = productlist.Where(c => c.ProductType == type).ToList();
}
//set select items for the DropDownList
ViewBag.Types = _repo.GetProductViewModels().Select(c=>c.ProductType).Distinct().ToList().Select(c => new SelectListItem { Text = c, Value = c }).ToList();
return View(productlist);
}
结果是这样的:
如我们所见,主页面将刷新。所以,我更喜欢使用 JQuery Ajax 来加载局部视图。
推荐阅读
- python - /show_cart/ 处的 TypeError 只能将 str(不是“int”)连接到 str
- node.js - 无法启动 chrome [致命:zygote_host_impl_linux.cc(116)] 没有可用的沙箱
- python - 如何按升序复制数据框中的单元格,直到达到另一个数字?熊猫
- .htaccess - 如何使用引导程序隐藏php中的文件夹结构
- python - matplotlib 条形图自动标准化我的数据
- javascript - 如何检查变量是否不是假的,但 0 在 Javascript 中通过
- android - React 本机 android 构建失败,任务 ':app:lintVitalRelease' 执行失败。无法下载 groovy-all-2..4.15.jar
- mongodb - 在 Spring Data mongo DB 中,我们如何获取城市及其级别数
- python - 数字生成的复杂序列提供了一个意想不到的产品
- json - spring boot json到模型转换错误