Asp.Net MVC 3 应用程序中复杂子对象的集合? [英] Collection of complex child objects in Asp.Net MVC 3 application?

查看:22
本文介绍了Asp.Net MVC 3 应用程序中复杂子对象的集合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够在同一视图中更新模型及其所有子对象集合.我已经提到了这些例子:http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspxhttp://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ .

I want to be able to update a model and all its collections of child objects in the same view. I have been referred to these examples: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx and http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ .

例如,我有一个对象顾问,它有一个WorkExperiences"集合.所有这些都在实体框架模型中.在视图中,Consultant 对象的简单属性没有问题,但是我无法获取要显示的文本框的集合.我尝试按照上面链接中的示例进行操作,但不起作用.问题是,在这些示例中,模型只是一个列表(不是具有子列表属性的对象).而且,该模型再次是 EF 模型.出于某种原因,这似乎不像在这些示例中那样有效.

For example, I have an object Consultant, that has a collection of "WorkExperiences". All this is in an Entity Framework model. In the view, the simple properties of the Consultant object is no problem, but the collection I cannot get a textbox to show up for. I tried following the examples in the links above, but it doesn't work. The problem is, in those examples the model is just a list (not an object with a child list property). And also, the model again is an EF model. And for some reason that doesn't seem to work as in those examples.

为了简单起见,我尝试按照 Phil Haacks 示例的方式做一些事情,然后让视图显示文本框:

Just to make it simple, I tried to do something along the lines of Phil Haacks example, and just get the View to show the textbox:

@for (int i = 0; i < Model.WorkExperiences.Count; i++)
{
    Html.TextBoxFor(m => m.WorkExperiences[i].Name);
}

我尝试在控制器中为 ViewModel 创建一个新的 WorkExperience 对象:

I tried to create a new WorkExperience object in the controller for the ViewModel:

    public ActionResult Create(int id)
    {
        Consultant consultant = _repository.GetConsultant(id);
        DetailsViewModel vm = new DetailsViewModel();
        vm.WorkExperiences = consultant.WorkExperiences.ToList();
        vm.WorkExperiences.Add(new WorkExperience());           
        return View(vm);
    }

但是视图没有为 WorkExperience Name 属性显示任何空文本框.另一方面,如果我创建一个单独的视图只是为了添加一个新的 WorkExperience 对象,将一个新的空 WorkExperience 对象作为模型传递,这可以正常工作:

But the View doesn't show any empty textbox for the WorkExperience Name property. If on the other hand I create a separate View just for adding a new WorkExperience object, passing a new empty WorkExperience object as the model, this works fine:

@Html.EditorFor(model => model.Name)

这给了我一个空的文本框,我可以保存新对象.但是为什么我不能在与顾问对象相同的视图中执行此操作,并根据上面链接中的示例使用集合?

That gives me an empty textbox, and I can save the new object. But why can't I do this in the same view as the Consultant object, with collections according to the examples in the links above?

顺便说一句,这是对先前问题的后续问题,该问题将我指向上述链接,但我从未得到最终解决方案.如果需要更多信息,请参阅该问题:创建MVC 3 应用程序中模型中对象属性的视图?

BTW, this is sort of a follow-up question to an earlier one, that pointed me to the above links, but I never got to a final solution for it. See that question if more info is needed: Create Views for object properties in model in MVC 3 application?

更新:

根据下面的回答和评论,这是视图和 EditorTemplate 的更新:

According to answers and comments below, here's an update with the View and an EditorTemplate:

视图:

@model Consultants.ViewModels.DetailsViewModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Add work experience", "CreateWorkExperience", new { id = ViewBag.Consultant.Id })
</p>
<table>
    <tr>
        <th></th>
        <th>
            Name
        </th>

    </tr>

@foreach (var item in Model.WorkExperiences) {
    <tr>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
            @Html.ActionLink("Details", "Details", new { id = item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id = item.Id })
        </td>
        <td>
            @item.Name
        </td>

    </tr>

}

</table>

@for (int i = 0; i < Model. WorkExperiences.Count; i++)
{
    Html.EditorFor(m => m. WorkExperiences[i]);
}

(请注意,这一切并不是我最终会如何设计它,我现在所追求的只是让 WorkExperience 对象显示为一个空文本框来填写,并且能够添加和删​​除 Phil Haack 和 Steven Sanderson 示例中的文本框.)

(Please note that all this is not really how I'll design it in the end, all I am after right now is to get the WorkExperience object to show up as an empty textbox to fill out, and to be able to add and delete such textboxes as in Phil Haack's and Steven Sanderson's examples.)

编辑器模板:

@model Consultants.Models.WorkExperience


@Html.TextBoxFor(m => m.Name);

这个带有 EditorTemplate 的东西在 Phil Haack 的示例项目中运行良好,我下载了它来尝试,但是在这里,对于 EF 模型或任何问题,我根本没有得到任何文本框.视图中的表只是作为测试存在,因为在表中我确实获得了 WorkExperiences 的行,无论是添加空的 WorkExperience 对象还是填写其属性都无关紧要,行会显示每个对象.但同样,没有文本框...

This stuff with the EditorTemplate works fine in Phil Haack's sample project, which I downloaded to try, but here, with the EF model or whatever the problem is, I don't get any textbox at all. The table in the view is just there as a test, because in the table I do get the rows for WorkExperiences, whether I add an empty WorkExperience object or fill out its properties doesn't matter, the rows show up for each object. But again, no textbox...

推荐答案

例如,我有一个对象顾问,它有一个WorkExperiences"集合.所有这些都在一个实体框架模型中.

For example, I have an object Consultant, that has a collection of "WorkExperiences". All this is in an Entity Framework model.

这是您应该改进的第一件事:引入视图模型并且不要在视图中使用您的域模型.

That's the first thing you should improve: introduce view models and don't use your domain models into the view.

话虽如此,让我们继续讨论模板.因此,您可以完全消除在视图中编写循环的需要.

This being said let's move on to the templates. So you can completely eliminate the need to write loops in your views.

您的视图可能如下所示:

So here's how your view might look like:

@model Consultants.ViewModels.DetailsViewModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Add work experience", "CreateWorkExperience", new { id = ViewBag.Consultant.Id })
</p>
<table>
    <tr>
        <th></th>
        <th>
            Name
        </th>
    </tr>
    @Html.DisplayFor(x => x.WorkExperiences)
</table>

@Html.EditorFor(x.WorkExperiences)

我们尽可能使用显示模板和编辑器模板.现在让我们定义它们.

So as you can we are using a display template and an editor template. Let's define them now.

显示模板(~/Views/Shared/DisplayTemplates/WorkExperience.cshtml):

@model AppName.Models.WorkExperience
<tr>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id = Model.Id }) |
        @Html.ActionLink("Details", "Details", new { id = Model.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id = Model.Id })
    </td>
    <td>
        @Model.Name
    </td>
</tr>

编辑器模板(~/Views/Shared/EditorTemplates/WorkExperience.cshtml):

@model AppName.Models.WorkExperience
@Html.TextBoxFor(x => x.SomePropertyOfTheWorkExperienceModelYouWantToEdit)
...

这里重要的是命名约定.模板的名称应该是集合中项目类型的名称.例如,如果在您的视图模型中您有一个属性

What is important here is the naming convention. The name of the template should be the name of the type of the item in the collection. So for example if in your view model you have a property

public IEnumerable<Foo> { get; set; }

对应的模板应该叫Foo.cshtml,并且应该位于~/Views/Shared/DisplayTemplates~/Views/Shared/EditorTemplates 取决于它的角色.

the corresponding template should be called Foo.cshtml and should be located in ~/Views/Shared/DisplayTemplates or ~/Views/Shared/EditorTemplates depending on its role.

如您所见,我们已经摆脱了讨厌的循环.现在不仅视图看起来很干净,而且您可以获得输入字段的正确名称,以便您可以将值绑定回 post 操作.

So as you can see we have gotten rid of the nasty loops. Now not only that the views look clean, but you get correct names for the input fields so that you can bind the values back in the post action.

这篇关于Asp.Net MVC 3 应用程序中复杂子对象的集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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