在C#4,ASP.NET MVC 2和NHibernate的上下文中;我有以下情况:
我们假设一个与Product
有关联的实体ProductType
。
在产品编辑视图中;如何实现仅以优雅和干燥的方式基于ProductType关联显示产品属性的子集?即,对于ProductType属性的不同值,应显示不同的属性。
使用产品视图模型构建器,并从不同的视图模型使用我自己的Html.EditorForModel()
自动生成视图(包括下拉菜单和其他不是开箱即用的东西)?
对一个视图模型的属性进行属性并使用前面提到的Html.EditorForModel()
方式?
使用一个模型,但实现不同的Web控件(查看策略)(可以干完吗?)?
还有其他什么吗?
答案 0 :(得分:1)
啊,我明白了 - 道歉。这不是“技术上”支持的 - 但是,您可以更改自定义属性以使用一些时髦的反射来实现相同的功能。但这绝对不是最好的做法。
另一个选择是使用Html.EditorFor(m => m.ProduceView()),其中ProduceView是一个基于属性状态返回新ViewModel类型的方法 - 所以如果设置了一些Property,然后ProduceView发送一个SetPropertyViewModel或一个NotSetPropertyViewModel,两者都实现了一些基类或接口。然后可以以不同方式对每个视图模型进行注释。
答案 1 :(得分:1)
我的第一步是创建一个视图模型。即使这与您的实际实体非常相似,分离也很重要。所以我会创建一个ProductEditViewModel
类。
接下来,根据不同的产品类型确定将要更改的属性。为每种产品类型创建单独的部分视图模型。这允许您控制显示哪些属性以及如何格式化它们。
在主产品编辑视图中,根据需要使用switch语句“交换”不同的部分视图。如果您使用AJAX,您甚至可以动态地执行此操作。
在此示例中,我们有许多不同的报告具有不同的报告类型。报告的主要部分不会改变,只是一些不同的参数(取决于类型)。
对于每种报告类型,我们都有单独的部分视图,您可以根据报告类型添加这些视图。此代码段位于<% using (Html.BeginForm()) %>
代码块内。
<% switch (Model.ReportType)
{
case (int)ReportType.summary:
Html.RenderPartial("Edit/SummaryControl", Model);
break;
case (int)ReportType.exception:
Html.RenderPartial("Edit/ExceptionControl", Model);
break;
case (int)ReportType.leakdetection:
Html.RenderPartial("Edit/LeakDetectionControl", Model);
break;
} %>
和摘要报告部分视图:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Footprint.Web.ViewModels.ReportsEditViewModel>" %>
<fieldset>
<legend>Summary Report Parameters</legend>
<div class="editor-label">
<%= Html.LabelFor(model => model.Frequency)%>
</div>
<div class="editor-field">
<%= Html.DropDownListFor( model => model.Frequency,Model.Frequencies) %>
<%= Html.ValidationMessageFor(model => model.Frequency)%>
</div>
<div class="editor-label">
</div>
<div class="editor-field">
<%= Html.CheckBoxFor(model => model.Combine) %><%= Html.LabelFor(model => model.Combine)%>
</div>
</fieldset>
HTH
答案 2 :(得分:0)
如果添加属性,则可以使用EditorForModel并仅显示属性的子集:
[ScaffoldColumn(false)]
到您不想要显示的属性。当然,如果您实现自己的自定义编辑器模板,那么您可以完全控制HTML呈现的内容。
答案 3 :(得分:0)
创建一个自定义DataAnnotationAttribute,它将ProductType作为参数。然后应用于要查看的相应属性。您可以通过为Product创建一个EditorTemplate来进一步扩展此功能,该EditorTemplate将处理进一步的进程,表单元素外观,或者某些表单元素的JQuery。
答案 4 :(得分:0)
我已经审核了所有答案,并通过更彻底的思考来解决问题。我选择了像
这样的方法使用产品视图模型构建器,和 来自不同的视图模型 使用自动生成视图 我自己的Html.EditorForModel() (包括下拉和其他东西 不是开箱即用的)?
来自我原来的问题。
我有一个视图模型创建者,它接受相应域模型实体的实例,以及域模型中用于下拉列表的不同列表。
我没有使用开箱即用的EditorFor/EditorForModel
,而是根据Brad Wilson的想法described in this post创建了自己的自定义模板。
DRY,简单明了(虽然我希望我不止一次使用动态语言来减少代码并摆脱一些反思......)。