我有一个很长的形式,我已经分成了几个部分,我正在使用@ Html.EditorFor,每个部分工作得很好但需要你思考这个方法是否可以改进。
有分段,每个分段都可以有多个活动,所以我有一个分段集合,此集合中的每个分段都包含一系列活动。
public class Activity
{
public string ActivityId { get; set; }
public string ActivityDescription { get; set; }
public bool IsSelected { get; set; }
}
public class Segment
{
public string SegmentId { get; set; }
public string SegmentDescription { get; set; }
public List<Activity> Activitites { get; set; }
}
这就是我希望我用作视图模型的ViewModel看起来如何,但由于@ Html.EditorFor没有接受集合类型,因此无法使其工作。
public class UserPreferencesViewModel
{
//..... Other Properties
public List<Segment> Segments {get; set;}
}
这是ViewModel
@model UserPreferencesViewModel
@{
//... Other Properties
@Html.EditorFor(m => m.Segments) //I assigned Segments three Segments in the Controller Get Method
}
以下是分段编辑器模板
@model List<Segment>
@{
//... Other Properties
@foreach(var segment in Model)
{
//Do the stuff
}
}
但是这并不能说EditorFor无法获取集合,并且在RunTime中抛出了异常。
这是我的工作。我创建了另一个Class&#34; UglySegmentWorkAround&#34;其中包含Segment Collection,然后在UserPreferencesViewModel中删除了List Property,而是为其定义了一个属性。
public class UglySegmentWorkAround
{
public List<Segment> Segments {get; set;}
}
public class UserPreferencesViewModel
{
//..... Other Properties
public UglySegmentWorkAround UglySegmentWorkAround {get; set;}
}
这是EditorFor Template。
@model UglySegmentWorkAround
@{
//... Other Properties
@foreach(var segments in Model.Segments)
{
//Do the stuff
}
}
它完美无缺,但我对这种方法感到不舒服,第一种方法中有什么我想念的吗?应该怎么做?如果我将它传递给集合,我不希望EditorFor执行隐式循环,因为我在EditorFor中渲染了一个复杂的UI结构,我需要EditorFor在其中包含循环。
答案 0 :(得分:29)
EditorFor旨在为您迭代集合。它会自动执行此操作。将集合传递给EditorFor时,它会自动为集合中的每个项目调用模板。
如果您需要为整个集合设置一些渲染,那么您应该在EditorFor调用之外,在视图代码中或在调用EditorFor的局部视图中执行此操作。
例如,如果你想把你的代码放在一个表中,你会这样做(MyCollection是List<MyItem>
):
_MyCollectionPartial.cshtml
<table>
<tr>
<th>Foo...</th>
...
<tr>
@Html.EditorFor(x => x.MyCollection)
</table>
/Views/Shared/EditorTemplates/MyItem.cshtml
@model MyItem
<tr>
<td>@Html.TextBox(x => x.Foo)</td>
....
</tr>
编辑:
也许更好的方法是使用编辑器模板的一个鲜为人知且记录不完整的“功能”。而“特征”是指如果您将模板名称指定为参数,则它不会迭代集合。您可以使用此表单“包装”您的收藏项模板。
/Home/Index.cshtml
.... your html
@Html.EditorFor(model => model.MyCollection, "MyCollectionLayout")
/Views/Shared/EditorTemplates/MyCollectionLayout.cshtml
@model List<MyItem>
<table>
<tr>
<th>Foo...</th>
...
<tr>
@Html.EditorForModel() (Or alternatively @Html.EditorFor(model => model)
</table>
/Views/Shared/EditorTemplates/MyItem.cshtml
@model MyItem
<tr>
<td>@Html.TextBoxFor(x => x.Foo)</td>
....
</tr>
注意:我说“功能”,因为这在SO上产生了许多问题,关于它在参数中明确指定模板名称时不会迭代集合)