ASP.NET MVC 5从客户端的单个源创建多个DropDownLists

时间:2014-07-24 07:36:58

标签: asp.net-mvc

我想知道是否有办法在客户端创建多个DropDownLists来自模型中的一个源。

背景是我需要创建一个包含大约30个DropDownLists的视图。 DropDownLists彼此相同,每个包含大约400个条目。我的模型包含一个

List<SelectListItem> StandardProductTypes

保存每个DropDownList的所有条目。

以下是我目前的观点:

@for (int i = 0; i < Model.Mappings.Count; i++)
{
    @Html.DropDownListFor(model => model.Mappings[i].SelectedStandardProductTypeKey,
                        new SelectList(Model.StandardProductTypes, "Value", "Text", Model.Mappings[i].SelectedStandardProductTypeKey))
}

如您所见,这是从服务器返回30 x 400 = 12000个条目,页面加载速度相当慢。

所有真正需要的只是传输了400个条目,并且它们在浏览器中在客户端复制了30次。有没有办法实现这一目标?任何对阅读材料或教程的参考都会很好。

提前致谢。

不然

2 个答案:

答案 0 :(得分:1)

用jQuery复制怎么样?

$('#myDropDownlist1 option').clone().appendTo('#myDropDownlist2');

答案 1 :(得分:0)

首先,您无需为每个DropDownList创建一个新的SelectList作为源。 DropDownListFor方法只需要IEnumerable<SelectListItem>作为源,您已经拥有(并且所选值由正常的属性值确定,因此您不需要明确地将其传递给选定的价值。

即给出&#34; StandardProductTypes&#34;已经IEnumberable<SelectListItem>你可以从

简化你的DropDownListFor
 @Html.DropDownListFor(model => model.Mappings[i].SelectedStandardProductTypeKey,
                        new SelectList(Model.StandardProductTypes, "Value", "Text", Model.Mappings[i].SelectedStandardProductTypeKey))

 @Html.DropDownListFor(model => model.Mappings[i].SelectedStandardProductTypeKey,
                        Model.StandardProductTypes)

此外,我通常不会在模型中添加List<SelectListItem>这样的内容,因为您不需要在回发后将其传回。在Viewbag中使用它很好。

然而,这只是一个很好的做法,除此之外,这里的HTML仍将包含所有下拉列表的所有选项。要解决您的问题,您只想返回一次,然后使用一些客户端jQuery / javascript来复制它

EG:

使用

@Html.DropDownListFor(model => model.Mappings[i].SelectedStandardProductTypeKey, new List<SelectListItem>())
@Html.Hidden(String.Format("Mappings[{0}].SelectedStandardProductTypeKey_Initial",i), Model.Mappings[i].SelectedStandardProductTypeKey) 

代替下拉列表(所以你有正确的初始值)

然后在最后添加一些脚本来填充下拉列表:

<script>
var ddlVals= new Array();
@foreach(var item in Model.StandardProductTypes) // get all the select list items into a javascript array
{
   @Html.Raw(String.Format("ddlVals.push(['{0}','{1}']);", item.Key, item.Value))
}

$('input[type="select"][name$="SelectedStandardProductTypeKey"]').each(function()
{
   var initValue $("name='" + $(this).attr("name") + "_Initial'").val();
   foreach(var item in ddlVals)
   {
     var html = '<option value="' + item[0] + '"'
     if (item[0] == initValue){ html = html + ' selected="selected"'} 
     html = html + '>' + item[1] + '</option>';
     $(this).append(html);
   }
}

</script>

修改

可以更快地使用Edi G's answer

中的想法

但您仍然需要选择正确的初始值。

所以保持上面的隐藏字段和下拉列表,但不是以前的脚本如何:

<!-- a template dropdownlist - hidden from view -->
@Html.DropdownList("ddlTemplate", Model.StandardProductTypes, new {id = "ddlTemplate", style="display:none;"})
<script>
$('input[type="select"][name$="SelectedStandardProductTypeKey"]').each(function()
    {
       $('#ddlTemplate option').clone().appendTo($(this));
       var initValue $("name='" + $(this).attr("name") + "_Initial'").val();
       $(this).val(initValue);
    }
</script>

编辑2

如果在上面编辑中尝试脚本后javascript正在填充下拉列表时仍然发现页面没有响应,那么我还有另一种可能的解决方案。

您基本上需要使用新的List<SelectListItem>填充每个下拉列表 - 每个下拉列表只包含一个选定的选项。

填充一个值数组(根据原始脚本),但是当你第一次删除下拉列表时,不是立即填充所有下拉列表,而是有一些javascript填充数组中的剩余值。

这样你只需加载400个项目的完整列表,而单击下拉列表时客户端javascript只需要工作,而不是在页面加载时下载所有30个下拉列表。