asp.net-mvc - MVC 3 Razor View 中的级联下拉菜单

标签 asp.net-mvc asp.net-mvc-3 razor

我对如何在 Razor View 中实现地址的级联下拉列表感兴趣。我的站点实体有一个 SuburbId 属性。 Suburb 有一个 CityId,City 有 ProvinceId。我想在站点 View 上显示所有郊区、城市和省的下拉菜单,例如郊区下拉列表最初将显示“首先选择一个城市”,城市下拉列表将显示“首先选择一个省份”。选择省份时,该省份的城市人口等。

我怎样才能实现这个目标?我从哪里开始?

最佳答案

我们用一个例子来说明一下。一如既往地从模型开始:

public class MyViewModel
{
    public string SelectedProvinceId { get; set; }
    public string SelectedCityId { get; set; }
    public string SelectedSuburbId { get; set; }
    public IEnumerable<Province> Provinces { get; set; }
}

public class Province
{
    public string Id { get; set; }
    public string Name { get; set; }
}

接下来是 Controller :

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            // TODO: Fetch those from your repository
            Provinces = Enumerable.Range(1, 10).Select(x => new Province
            {
                Id = (x + 1).ToString(),
                Name = "Province " + x
            })
        };
        return View(model);
    }

    public ActionResult Suburbs(int cityId)
    {
        // TODO: Fetch the suburbs from your repository based on the cityId
        var suburbs = Enumerable.Range(1, 5).Select(x => new
        {
            Id = x,
            Name = "suburb " + x
        });
        return Json(suburbs, JsonRequestBehavior.AllowGet);
    }

    public ActionResult Cities(int provinceId)
    {
        // TODO: Fetch the cities from your repository based on the provinceId
        var cities = Enumerable.Range(1, 5).Select(x => new
        {
            Id = x,
            Name = "city " + x
        });
        return Json(cities, JsonRequestBehavior.AllowGet);
    }
}

最后是一个 View :

@model SomeNs.Models.MyViewModel

@{
    ViewBag.Title = "Home Page";
}

<script type="text/javascript" src="/scripts/jquery-1.4.4.js"></script>
<script type="text/javascript">
    $(function () {
        $('#SelectedProvinceId').change(function () {
            var selectedProvinceId = $(this).val();
            $.getJSON('@Url.Action("Cities")', { provinceId: selectedProvinceId }, function (cities) {
                var citiesSelect = $('#SelectedCityId');
                citiesSelect.empty();
                $.each(cities, function (index, city) {
                    citiesSelect.append(
                        $('<option/>')
                            .attr('value', city.Id)
                            .text(city.Name)
                    );
                });
            });
        });

        $('#SelectedCityId').change(function () {
            var selectedCityId = $(this).val();
            $.getJSON('@Url.Action("Suburbs")', { cityId: selectedCityId }, function (suburbs) {
                var suburbsSelect = $('#SelectedSuburbId');
                suburbsSelect.empty();
                $.each(suburbs, function (index, suburb) {
                    suburbsSelect.append(
                        $('<option/>')
                            .attr('value', suburb.Id)
                            .text(suburb.Name)
                    );
                });
            });
        });
    });
</script>

<div>
    Province: 
    @Html.DropDownListFor(x => x.SelectedProvinceId, new SelectList(Model.Provinces, "Id", "Name"))
</div>
<div>
    City: 
    @Html.DropDownListFor(x => x.SelectedCityId, Enumerable.Empty<SelectListItem>())
</div>
<div>
    Suburb: 
    @Html.DropDownListFor(x => x.SelectedSuburbId, Enumerable.Empty<SelectListItem>())
</div>

作为一项改进,可以通过编写 jquery 插件来缩短 javascript 代码,以避免重复某些部分。

<小时/>

更新:

谈论插件时,您可能会想到以下内容:

(function ($) {
    $.fn.cascade = function (options) {
        var defaults = { };
        var opts = $.extend(defaults, options);

        return this.each(function () {
            $(this).change(function () {
                var selectedValue = $(this).val();
                var params = { };
                params[opts.paramName] = selectedValue;
                $.getJSON(opts.url, params, function (items) {
                    opts.childSelect.empty();
                    $.each(items, function (index, item) {
                        opts.childSelect.append(
                            $('<option/>')
                                .attr('value', item.Id)
                                .text(item.Name)
                        );
                    });
                });
            });
        });
    };
})(jQuery);

然后简单地将其连接起来:

$(function () {
    $('#SelectedProvinceId').cascade({
        url: '@Url.Action("Cities")',
        paramName: 'provinceId',
        childSelect: $('#SelectedCityId')
    });

    $('#SelectedCityId').cascade({
        url: '@Url.Action("Suburbs")',
        paramName: 'cityId',
        childSelect: $('#SelectedSuburbId')
    });
});

关于asp.net-mvc - MVC 3 Razor View 中的级联下拉菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4458970/

相关文章:

javascript - Bootstrap 导航选项卡未突出显示事件选项卡

asp.net - 如何在Visual Studio 2015的一种解决方案中跨多个ASP.NET CORE项目共享诸如appsettings.json之类的配置文件?

c# - 使用 C# 在 ASP.NET MVC 3 中创建级联下拉列表的最简单方法

asp.net-mvc-3 - ASP.NET MVC 3 : Purpose of IgnoreRoute ("{resource}.axd/{*pathInfo}"); ? 已弃用?

asp.net - POST URL 在 Razor 页面中缺少处理程序查询字符串

c# - 如何在 MVC 4 中显示来自路径的图像?

asp.net-mvc - 如何替换 Asp.net MVC 2 中的默认 ModelState 错误消息?

javascript - 使用 Json 填充剑道网格时出错

jquery - 如何在按钮单击事件上调用验证,该事件不是提交类型而是按钮类型并且没有表单?

asp.net-mvc - 成功和错误函数在 Ajax 调用中未触发