在ASP.NET MVC传递一个集合到EditorFor [英] Passing a Collection to EditorFor in ASP.NET MVC

查看:196
本文介绍了在ASP.NET MVC传递一个集合到EditorFor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个漫长的形式,我打破了几个部分,并使用@ Html.EditorFor为其伟大的工作,每个部分我却需要这种方法是否能改善或没有你的看法。

I have a lengthy form which I have broken to several parts and am using @Html.EditorFor for each section which is working great but need your thoughts on whether this approach can be improved or not.

有段和每段可以有多个活动,让我有段的集合,并在此集合中的每个段包含活动的集合。

There are Segments and Every Segment can have Multiple Activities, So I have a Collection of Segments and every Segment in this collection contains a Collection of Activities.

    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; }
    }

这是我多想,我作为视图应该看起来像一个模型中使用,但不能做,因为@ Html.EditorFor它的工作没有接受集合类型的视图模型。

This was how I wanted the ViewModel that I use as a model for the view should look like but couldn't make it to work since @Html.EditorFor didn't accept a Collection Type.

    public class UserPreferencesViewModel
   {
       //..... Other Properties
       public List<Segment> Segments {get; set;}
   }

下面是视图模型

@model UserPreferencesViewModel
@{
   //... Other Properties
   @Html.EditorFor(m => m.Segments) //I assigned Segments three Segments in the Controller Get Method
}

下面是EditorFor模板段

Here is the EditorFor Template for Segments

@model List<Segment>
@{
   //... Other Properties
   @foreach(var segment in Model)
   {
      //Do the stuff
   }
}

但是,这并不工作,说EditorFor不能采取集合和异常在运行时抛出。

But this doesn't work saying EditorFor cannot take collections and the exception is thrown at RunTime.

下面是我的解决。我创建了另一个班UglySegmentWorkAround,它包含段集合,然后在用户preferencesViewModel我删除了列表属性,而是定义为一个属性。

Here is my work Around. I created another Class "UglySegmentWorkAround" which contains the Segment Collection and then in the UserPreferencesViewModel I removed the List Property and instead defined a property for that.

public class UglySegmentWorkAround
{
public List<Segment> Segments {get; set;}
}

public class UserPreferencesViewModel
       {
           //..... Other Properties
           public UglySegmentWorkAround UglySegmentWorkAround {get; set;}
       }

和这里是EditorFor模板。

and Here is the EditorFor Template.

@model UglySegmentWorkAround
    @{
       //... Other Properties
       @foreach(var segments in Model.Segments)
       {
          //Do the stuff
       }
    }

它可以完美,但我只是感觉不舒服,这种方法是有什么我在第一种方法缺少什么?这个应该怎么做呢?我不希望EditorFor如果我通过它集合因为我呈现在EditorFor一个复杂的UI结构,我需要的EditorFor有里面的循环做一个隐含的循环。

It works perfectly but I just don't feel comfortable with this approach, is there anything I am missing in the first approach? How this should be done? I don't want the EditorFor to do an implicit loop if I Pass it a collection because I am rendering a complex UI structure in the EditorFor and I need the EditorFor to have the loop inside it.

推荐答案

EditorFor的设计迭代集合为您服务。它会自动完成。当你传递一个集合到一个EditorFor,它会自动调用您的模板为集合中的每个项目。

EditorFor is designed to iterate over collections for you. It does this automatically. When you pass a collection into an EditorFor, it will automatically call your template for each item in the collection.

如果您需要设置一些渲染为集合作为一个整体,那么你应该这样做的EditorFor通话外,可以在你看来code或其中调用你EditorFor的局部视图。

If you need to setup some rendering for the collection as a whole then you should do this outside of the EditorFor call, either in your view code, or in a partial view which calls your EditorFor.

举例来说,如果你想要把你的code在一个表中,你可以这样做(其中MyCollection的是列表&LT; MyItem&GT; ):

For instance, if you want to put your code in a table, you would do this (where MyCollection is List<MyItem>):

_MyCollectionPartial.cshtml

_MyCollectionPartial.cshtml

<table>
    <tr>
       <th>Foo...</th>
       ...
     <tr>
     @Html.EditorFor(x => x.MyCollection)
</table>

/Views/Shared/MyItem.cshtml

/Views/Shared/MyItem.cshtml

@model MyItem
<tr>
    <td>@Html.TextBox(x => x.Foo)</td>
    ....
</tr>

编辑:

也许一个更好的方式来做到这一点是使用编辑器模板一个鲜为人知的和不良记录功能。和功能是,如果你指定一个模板名作为参数的话,就不会在集合上迭代。您可以使用此表来包装您的收藏项模板。

Perhaps a better way to do this is to use a little known and poorly documented "feature" of Editor templates. And that "feature" is that if you specify a template name as an argument, then it does not iterate over the collection. You can use this form to "wrap" your collection item templates.

/Home/Index.cshtml

/Home/Index.cshtml

.... your html
@Html.EditorFor(model => model.MyCollection, "MyCollectionLayout")

/Views/Shared/MyCollectionLayout.cshtml

/Views/Shared/MyCollectionLayout.cshtml

@model List<MyItem>
<table>
    <tr>
       <th>Foo...</th>
       ...
     <tr>
     @Html.EditorForModel() (Or alternatively @Html.EditorFor(model => model)
 </table>

/Views/Shared/MyItem.cshtml

/Views/Shared/MyItem.cshtml

@model MyItem
<tr>
    <td>@Html.TextBoxFor(x => x.Foo)</td>
    ....
</tr>

请注意:我说的功能,因为这对SO它不遍历时,模板名称中的参数明确指定)集合在这里产生了许多问题。

NOTE: I say "feature" because this has generated many questions here on SO about it not iterating over collections when the template name is explicitly specified in the arguments)

这篇关于在ASP.NET MVC传递一个集合到EditorFor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆