在ASP.NET MVC中将集合传递给EditorFor

时间:2014-09-26 21:34:04

标签: asp.net asp.net-mvc razor editorfor

我有一个很长的形式,我已经分成了几个部分,我正在使用@ 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在其中包含循环。

1 个答案:

答案 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上产生了许多问题,关于它在参数中明确指定模板名称时不会迭代集合)