我正在使用梅尔(Mel)的空间中建议的解决方案(https://mleeb.wordpress.com/2013/11/23/editing-nested-lists-in-asp-mvc-4/)编辑嵌套列表
基本上我的模型如下
ProductEditModel
--> ProductAudioEditModel
--> ProductAssetResourceEditModel
我在下面工作
@Html.EditorFor(c => resource.TrackTitle, null, Html.GetHtmlName("TrackTitle"))
在编辑时为我提供了正确的值。
但是,我无法在DropDownList上使用它,或者无法在dropdownlist中选择编辑后的值。它始终为我提供控制器中的原始值。
@using (Html.BeginCollectionItem("ProductAssetAudios", out parentIdentifier))
{
.....
@foreach (var resource in Model.ProductAssetResources.OrderBy(a => a.ResourceNumber))
{
string childIdentifier = null;
@using (Html.BeginChildCollectionItem("ProductAssetResources", parentIdentifier, out childIdentifier))
{
@Html.HiddenFor(model => resource.AssetResourceStatusId, new { Name = Html.GetHtmlName(childIdentifier, "AssetResourceStatusId") })
@Html.DropDownListFor(model => resource.AssetResourceStatusId, new SelectList(visibleResourceStatuses, "AssetResourceStatusId", "Name", resource.AssetResourceStatusId), new { @class = "inherit-title" }) @Html.ValidationMessageFor(model => resource.AssetResourceStatusId)
}
}
}
即使为其他值选择了下拉列表,AssetResourceStatusId始终保持原始值。
我希望在编辑嵌套列表时,EditorFor和DropDownListFor应该以相同的方式工作。
生成的HTML
<select class="inherit-title valid" id="ProductAssetAudios_0df86a5c-0a32-4b0f-97ee-3b3254f743d9__ProductAssetResources_c58ba43c-6081-41d4-88fd-d59799c7374e__resource_AssetResourceStatusId" name="ProductAssetAudios[0df86a5c-0a32-4b0f-97ee-3b3254f743d9].ProductAssetResources[c58ba43c-6081-41d4-88fd-d59799c7374e].resource.AssetResourceStatusId" aria-invalid="false"><option value="3">Extra</option>
<option selected="selected" value="2">Found</option>
<option value="8">Ignore</option>
</select>
<input name="ProductAssetAudios[b5670a6a-7a1d-4c76-86bc-85a05cd144c1].ProductAssetResources[aa378d38-0fb7-4304-9f24-79d0efcb36b9].AssetResourceStatusId" data-val="true" data-val-number="The field AssetResourceStatusId must be a number." data-val-required="The AssetResourceStatusId field is required." id="ProductAssetAudios_b5670a6a-7a1d-4c76-86bc-85a05cd144c1__ProductAssetResources_aa378d38-0fb7-4304-9f24-79d0efcb36b9__resource_AssetResourceStatusId" type="hidden" value="2">
-艾伦-
您的模型包含一个名为ProductAssetAudios
(typeof ProductAudioEditModel
)的集合属性,并且该集合中的每个对象都包含一个名为ProductAssetResources
(typeof ProductAssetResourceEditModel
)的集合属性,并且每个对象都包含一个名为的属性AssetResourceStatusId
。
在C#代码中,如果要AssetResourceStatusId
在1stProductAssetResourceEditModel
中获取1st的值,则ProductAudioEditModel
代码为
var id = model.ProductAssetAudios[0].ProductAssetResources[0].AssetResourceStatusId;
删除model
前缀,这恰好name
是控件的属性必须是的方式。什么BeginCollectionItem()
和BeginChildCollectionItem()
方法做的是修改集合索引到Guid
,并增加了索引一个隐藏的输入,让您可以动态地从集合添加或删除项目。默认情况下,DefaultModelBinder
除非将索引器的值也发布(即添加隐藏输入的原因),否则它将绑定从零开始的连续索引器的集合。
在您的情况下,name
隐藏输入的属性是正确的,即使用
@Html.HiddenFor(model => resource.AssetResourceStatusId, new { Name = Html.GetHtmlName(childIdentifier, "AssetResourceStatusId") })
因为您要覆盖由name
生成的默认属性HiddenFor()
。您只需要对方法做同样的事情DropDownListFor()
,即使用设置name属性new { Name = Html.GetHtmlName(childIdentifier, "AssetResourceStatusId") }
。但是随后,您还需要删除隐藏的输入,因为DefaultModelBinder
只会绑定为属性发布的第一个值。另请注意,您还需要更改ValidationMessageFor()
。
边注。从注释看来,您不想在视图中添加和删除项目,在这种情况下,请不要使用BeginCollectionItem()
和BeginChildCollectionItem()
方法。相反,只需对typeof和使用嵌套for
循环或自定义。使用循环的一个例子是EditorTemplates
ProductAudioEditModel
ProductAssetResourceEditModel
for
for(int i = 0; i < Model.ProductAssetAudios.Count; i++)
{
@Html.TextBoxFor(m => m.ProductAssetAudios[i].SomeProperty)
....
for (int j = 0; j < Model.ProductAssetAudios[i].ProductAssetResources.Count; j++)
{
@Html.DropDownListFor(m => m.ProductAssetAudios[i].ProductAssetResources[j].AssetResourceStatusId, new SelectList(.....)
另请参阅此答案以获取使用nested的示例EditorTemplate
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句