在编辑视图中显示视图模型属性的不同子集

时间:2010-04-29 18:38:58

标签: c# asp.net-mvc

在C#4,ASP.NET MVC 2和NHibernate的上下文中;我有以下情况:

我们假设一个与Product有关联的实体ProductType

在产品编辑视图中;如何实现仅以优雅和干燥的方式基于ProductType关联显示产品属性的子集?即,对于ProductType属性的不同值,应显示不同的属性。

使用产品视图模型构建器,并从不同的视图模型使用我自己的Html.EditorForModel()自动生成视图(包括下拉菜单和其他不是开箱即用的东西)?

对一个视图模型的属性进行属性并使用前面提到的Html.EditorForModel()方式?

使用一个模型,但实现不同的Web控件(查看策略)(可以干完吗?)?

还有其他什么吗?

5 个答案:

答案 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,简单明了(虽然我希望我不止一次使用动态语言来减少代码并摆脱一些反思......)。