我想知道是否有办法在客户端创建多个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次。有没有办法实现这一目标?任何对阅读材料或教程的参考都会很好。
提前致谢。
不然
答案 0 :(得分:1)
用jQuery复制怎么样?
$('#myDropDownlist1 option').clone().appendTo('#myDropDownlist2');
答案 1 :(得分:0)
首先,您无需为每个DropDownList创建一个新的SelectList作为源。 DropDownListFor方法只需要IEnumerable<SelectListItem>
作为源,您已经拥有(并且所选值由正常的属性值确定,因此您不需要明确地将其传递给选定的价值。
即给出&#34; StandardProductTypes&#34;已经IEnumberable<SelectListItem>
你可以从
@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个下拉列表。