2012-03-15 28 views
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(); 
    } 
} 

解决方案

Solution explorerIEnumerable的在我的视图模型不与EditorForModel

视图(_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> 
} 

SelectListItem.cshtml

显示10
@model IEnumerable<SelectListItem> 

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

<p>Test</p> 

结果

完整映像:http://i.imgur.com/I7HxA.png

View result

  • 我试图把属性 “UIHint”,但仍显示什么!

问题

我在做什么错?

回答

3

默认情况下,当您使用Html.EditorForModel时,不要期望这会缓解到复杂属性,例如Tipos属性,该属性类型为IEnumerable<SelectListItem>。布拉德威尔逊在他的blog post(更具体地阅读浅的潜水与深潜部分接近结束的帖子)解释了这一点。如果您希望发生这种情况,您需要为对象类型编写自定义编辑器模板。

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

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

记住,对于SelectListItem编辑器模板是错误的,因为你的DropDownListFor结合模型作为第一个参数还承担。不要忘记,这个帮助器的第一个参数必须是一个标量属性,用来保存选定的值。您需要在视图模型上为此设置字符串或整数属性。第二个参数表示集合。

有关编辑模板的另一个重要方面是,当你有IEnumerable<T>类型的属性,并呼吁T.cshtml编辑模板,这个编辑器模板必须是强类型的T类,而不是作为IEnumerable<T>你与你的SelectListItem.cshtml模板一样。如果您使用UIHint或将模板名称指定为EditorFor helper的第二个参数,则这不适用。在这种情况下,模板将被输入到集合中。

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

+0

感谢您的解释..我不会这样做每个属性,我会至少使用'UIHint'属性。问题是,即使我添加了'UIHint',没有任何反应! – ridermansb 2012-03-15 17:06:51

+1

@Riderman de Sousa Barbosa,没有任何反应,因为正如我所说的,在默认的对象模板中,ASP.NET MVC不会递归到复杂的属性。所以即使你在你的Tipos属性上放置一个UIHint,它也会被忽略。您需要修改Brad Wilson显示的默认Object.cshtml模板。 – 2012-03-15 17:12:09

+0

我明白了。那么我想避免这种情况,但我必须这样做。谢谢您的帮助! – ridermansb 2012-03-15 17:15:44

1

A @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

相关问题