2

视图模型

[Validator(typeof(ProdutoCategoriaValidator))]
public class ProdutoCategoriaViewModel
{
    [HiddenInput(DisplayValue = false)]
    public Guid ID { get; set; }

    public IEnumerable<SelectListItem> Tipos { get; set; }  // <<<<-------  Is not showing in my view

    [AdditionalMetadata("data-bind", "event: { change: function(data) { Link(data.Nome());  }}")]
    public string Nome { get; set; }

    [DataType(DataType.Url)]
    [AdditionalMetadata("Prefixo", "Produtos/{tipo-de-produto}#")]
    public string Link { get; set; }

    public int? Ordem { get; set; }

    public ProdutoCategoriaViewModel()
    {
        ID = Guid.NewGuid();
    }
}

解决方案

解决方案浏览器

查看 (_Formulario.cshtml)

@model ProdutoCategoriaViewModel
@using (Html.BeginForm(null, null, FormMethod.Post, new { id="form-produtocategoria", data_bind = "submit: salvar" }))
{
    @Html.AntiForgeryToken()

    <legend>@Html.MvcSiteMap().SiteMapTitle()</legend>

    <fieldset>
        @Html.ValidationSummary(false, "Verifique os erros abaixo:")
        @Html.EditorForModel()
    </fieldset>

    <div class="buttons">
        @Html.ActionLink("Cancelar", "Index")
        <input type="submit" value="SALVAR" />
    </div>
}

选择列表项.cshtml

@model IEnumerable<SelectListItem>

@Html.DropDownListFor(m => m, Model)

<p>Test</p>

结果

完整图片:http: //i.imgur.com/I7HxA.png

查看结果

笔记

  • 我试图把属性“UIHint”,但仍然没有显示!

问题

我究竟做错了什么?

4

2 回答 2

3

默认情况下,当您使用Html.EditorForModel时不要期望它会递归到复杂的属性,例如您的Tipos属性类型为IEnumerable<SelectListItem>. Brad Wilson 在他的博客文章中解释了这一点(更具体地说,请阅读文章末尾的“浅潜与深潜”部分)。如果您希望发生这种情况,您将需要为 Object 类型编写自定义编辑器模板。

另一种可能性是指定模板名称:

@Html.EditorFor(x => x.Tipos, "SelectListItem")

还要记住,您的编辑器模板SelectListItem是错误的,因为您将 DropDownListFor 作为第一个参数绑定到模型。不要忘记这个助手的第一个参数必须是一个标量属性,用于保存选定的值。为此,您需要在视图模型上使用字符串或整数属性。第二个参数代表集合。

关于编辑器模板的另一个重要方面是,当您有一个类型的属性IEnumerable<T>和一个称为T.cshtml此编辑器模板的编辑器模板时,必须对T类进行强类型化,而不是IEnumerable<T>像您对SelectListItem.cshtml模板所做的那样。如果您使用 UIHint 或将模板名称指定为 EditorFor 帮助器的第二个参数,则这不适用。在这种情况下,模板将被键入到集合中。

回顾一下,您可以按照 Brad Wilson 的建议实现自定义对象编辑器模板,该模板将递归到复杂的属性,或者您可以修改_Formulario.cshtml视图以指定 EditorFor 每个单独的元素。

于 2012-03-15T16:51:36.570 回答
1

@foreach循环呈现看起来正确的东西,但生成的标记对于每一行的控件将具有相同的 id。它也不会将可枚举集合与模型实例一起发回。

有两种方法可以完成这项工作,这样您就可以为集合中的每个项目拥有一个唯一的 id,从而使集合在回发时得到补充:

1.使用默认的编辑器模板而不是一个命名的

// editor name parameter must be omitted; default editor template's model type
// should be a single instance of the child object, not an IEnumerable. This 
// convention looks wrong, but it fully works:
@Html.EditorFor(parentObject => parentObject.Items) 

2.使用@for循环,而不是@foreach

@for (int i = 0; i < parentObject.Items.Count ; i++) {
    // the model binder uses the indexer to disambiguate the collection items' controls: 
    @Html.EditorFor(c => Model.Items[i], "MyEditorTemplate") 
}

但是,这将不起作用:

// this will error out; the model type will not match the view's at runtime:
@Html.EditorFor(parentObject => parentObject.Items, "MyEditorTemplate")

这也不会:

@foreach(var item in parentObject.Items) {
    // this will render, but won't post the collection items back with the model instance: 
    @Html.EditorFor(c => item, "MyEditorTemplate") 
}

有关为什么会这样的详细答案,请查看以下问题:MVC can't override EditorTemplate name when used in EditorFor for child object

于 2013-08-02T13:33:31.153 回答