首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MVC 3 Razor视图中的级联下拉菜单

问MVC 3 Razor视图中的级联下拉菜单
EN

Stack Overflow用户
提问于 2010-12-16 17:00:07
回答 5查看 31.4K关注 0票数 47

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

我如何才能做到这一点?我该从哪里开始呢?

EN

回答 5

Stack Overflow用户

发布于 2010-12-16 17:15:18

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

代码语言:javascript
复制
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; }
}

接下来是控制器:

代码语言:javascript
复制
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);
    }
}

最后是一个视图:

代码语言:javascript
复制
@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代码,以避免重复某些部分。

更新:

在谈到插件时,你可能会有以下几句话:

代码语言: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);

然后简单地把它连接起来:

代码语言:javascript
复制
$(function () {
    $('#SelectedProvinceId').cascade({
        url: '@Url.Action("Cities")',
        paramName: 'provinceId',
        childSelect: $('#SelectedCityId')
    });

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

Stack Overflow用户

发布于 2012-02-08 08:22:23

感谢Darin为您提供解决方案。这对我说到点子上有很大帮助。但正如“xxviktor”所提到的,我确实得到了循环引用。错误。为了摆脱它,我已经这样做了。

代码语言:javascript
复制
    public string GetCounties(int countryID)
    {
        List<County> objCounties = new List<County>();
        var objResp = _mastRepo.GetCounties(countryID, ref objCounties);
        var objRetC = from c in objCounties
                      select new SelectListItem
                      {
                          Text = c.Name,
                          Value = c.ID.ToString()
                      };
        return new JavaScriptSerializer().Serialize(objRetC);
    }

为了实现自动级联,我以这种方式略微扩展了jQuery扩展。

代码语言:javascript
复制
        $('#ddlCountry').cascade({
            url: '@Url.Action("GetCounties")',
            paramName: 'countryID',
            childSelect: $('#ddlState'),
            childCascade: true
        });

实际的JS使用这个参数,如下所示(在JSON请求中)。

代码语言:javascript
复制
                // trigger child change
                if (opts.childCascade) {
                    opts.childSelect.change();
                }

希望这对有类似问题的人有所帮助。

票数 5
EN

Stack Overflow用户

发布于 2011-02-21 12:39:33

请注意,此解决方案不能直接与EF 4.0一起使用。它会导致“序列化时检测到循环引用...”错误。以下是可能的解决方案http://blogs.telerik.com/atanaskorchev/posts/10-01-25/resolving_circular_references_when_binding_the_mvc_grid.aspx,我使用了第二个解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4458970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档