如何正确绑定list< object>在MVC的创建视图中 [英] How to properly bind list<object> in the create view of MVC

查看:87
本文介绍了如何正确绑定list< object>在MVC的创建视图中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个与下面的假设类似的问题.我已经多次将局部视图添加到另一个视图,但是我不确定如何使它们正确绑定到视图模型等.此外,如果单个fooName错误,验证似乎会触发每个单个fooName.如您所见,我已经将索引添加到了视图包中,但是我还不确定如何使用它.

I have a problem similar to the hypothetical below. I have added partial views to another view multiple times but I'm not sure how to get them to bind properly to the view model etc. Also, the validation seems to trigger for every single fooName if a single fooName is wrong. I've added the index to the viewbag as you can see but I'm not really sure how to use it yet.

注意:使用MVC5.2

Note:Using MVC5.2

查看模型

public class Thing
{
    public String thingName { get; set; }
    public List<Foo> Foos { get; set; }
}
public class Foo
{
    public String fooName { get; set; }
}

Foo View

@model Project.Models.Foo

<div class="form-horizontal">
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })

    <div class="form-group">
        <div class="col-md-12">
            @Html.LabelFor(model => model.fooName, htmlAttributes: new { @class = "control-label" })
            @Html.EditorFor(model => model.fooName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.fooName, "", new { @class = "text-danger" })
        </div>
    </div>
</div>

事物视图

@model Project.Models.Thing
@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            <div class="col-md-12">
                @Html.LabelFor(model => model.thingName, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.thingName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.thingName, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>
    <div class="add-foo">
        @* at some point add more foos with ajax, for now k.i.s.s. *@
        @Html.Partial("/Views/Foo/Create.cshtml", new ViewDataDictionary { { "id", 1 } })
        @Html.Partial("/Views/Foo/Create.cshtml", new ViewDataDictionary { { "id", 2 } })
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
}

推荐答案

这里的问题是Foo部分在渲染时没有较大模型的上下文.结果,您会得到一堆具有相同名称和ID的输入,即:

The problem here is that the Foo partial is rendering without context of the larger model at play. As a result you're getting a bunch of inputs with all the same names and ids, i.e.:

<input type="text" name="fooName" id="fooName" class="form-control">
...
<input type="text" name="fooName" id="fooName" class="form-control">
...

这就是为什么对所有这些都触发​​验证的原因,因为它们都是相同的.为了使部分行为正确,您需要向其中传递一些上下文.例如,如果要遍历某事的现有实例,则可以执行以下操作:

That's why the validation is triggering on all of them, because they are all the same. In order to have the partial behave correctly, you would need to pass some context into it. For example, if you were iterating over existing instances of something you could do:

@for (var i = 0; i < Model.Foos.Count; i++)
{
    @Html.Partial("_Foo", Model.Foos[i])
}

基于Model.Foos[i]位,Razor随后将生成正确的输入名称,例如Foos[0].fooNameFoos[1].fooName等.

Based on the Model.Foos[i] bit, Razor would then generate proper input names like Foos[0].fooName, Foos[1].fooName, etc.

或者,您可以覆盖HtmlFieldPrefix:

@Html.Partial("_Foo", foo1, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Foos[0]" } })
@Html.Partial("_Foo", foo2, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Foos[1]" } })
...

由于您计划能够通过JavaScript动态添加其他项目,因此,最好的选择是依靠Knockout或Angular之类的内容来基于JavaScript数组为您呈现字段.然后,当您将新的Foo实例添加到该数组时,该库将自动使用索引名称属性将其他字段添加到页面.

Since you're planning on being able to add additional ones dynamically via JavaScript, your best bet though is to rely on something like Knockout or Angular to render the fields for you based on a JavaScript array. Then, when you add new Foo instances to that array, the library will automatically add additional fields to the page with an indexed name attribute.

这篇关于如何正确绑定list&lt; object&gt;在MVC的创建视图中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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