【问题标题】:Select onchange to Controller's Action in .net-core在 .net-core 中选择 onchange 到 Controller 的 Action
【发布时间】:2021-05-25 22:32:05
【问题描述】:

我有一个按类型分类的对象列表,所以我的视图中有一个“类型”选择

<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 
}

如何使用 select 正确地重新加载视图?

我看到提出了 Ajax 解决方案,这将是一个很好的解决方案,但是我的问题是,当我更改产品类型时,不仅产品列表会更改,而且产品特性(列)也会更改,创建按钮也应该仅创建该类型的产品,因此,它会更改所有视图行为。我宁愿重新加载所有视图而不是其中的一部分。

【问题讨论】:

    标签: .net asp.net-core .net-5 asp.net-core-tag-helpers asp.net-core-5.0


    【解决方案1】:

    如何使用 select 正确地重新加载视图?

    看来你想根据 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>
    }
    

    然后,结果如下:

    【注意】使用上述方法,主页面不会更新,只刷新局部视图。

    如果你想使用&lt;select&gt;元素onchange事件,你可以在Form中添加一个Submit按钮,在onchange事件中,点击Submit按钮,它将提交表单.然后,您可以根据类型过滤数据。

    将上面的代码修改如下:在ProductIndex.cshtml页面中,去掉JQuery脚本,添加提交按钮,为select元素添加name属性,然后,在选择onchange事件中,点击提交按钮:

    @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 来加载局部视图。

    【讨论】:

    • 我的问题是,当我更改产品类型时,不仅产品列表会发生变化,而且产品特性(列)也会发生变化,而且创建按钮应该只创建该类型的产品,所以,它更改所有视图行为。我宁愿重新加载所有视图而不是其中的一部分。
    • 嗨@Serge,“当我更改产品类型时,不仅产品列表发生变化,而且产品特性(列)也发生变化,”从最初的描述中,我们只是看到您想要更改根据选择的类型生成产品列表,如果要更改产品列,请详细说明,如果列不固定,可以考虑动态生成html内容。 “创建按钮应该只创建该类型的产品”对于这个问题,当您创建产品时,您可以获取下拉列表选择的值并将其与新产品一起发送,并存储它。
    • 此外,它们似乎是两个不同的问题,我建议您可以为它们创建一个新的单独线程并解释有关该问题的更多详细信息。
    猜你喜欢
    • 2022-12-04
    • 2018-02-05
    • 2016-12-22
    • 2018-05-24
    • 2019-12-03
    • 1970-01-01
    • 2020-11-18
    • 2020-06-04
    • 1970-01-01
    相关资源
    最近更新 更多