代码之家  ›  专栏  ›  技术社区  ›  Martin R-L

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

  •  0
  • Martin R-L  · 技术社区  · 14 年前

    在C#4、ASP.NET MVC 2和NHibernate的上下文中;我有以下场景:

    假设一个实体 Product ProductType .

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

    Html.EditorForModel() (包括下拉列表和其他非开箱即用的内容)?

    属性一个视图模型的属性并使用

    使用一个模型,但实现不同的web控件(视图策略)(可以干掉吗?)?

    完全是别的吗?

    5 回复  |  直到 14 年前
        1
  •  1
  •   Tejs    14 年前

    啊,我明白了-我道歉。这在“技术上”是不受支持的-但是,您可以更改一个自定义属性,使用一些时髦的反射来实现相同的功能。不过,这绝对不是最佳做法。

        2
  •  1
  •   Alastair Pitts    14 年前

    我的第一步是创建视图模型。即使这是非常类似于您的实际实体,分离是重要的。所以我要创造一个 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>
    

        3
  •  0
  •   Tejs    14 年前

    如果添加以下属性,则可以使用EditorForModel并仅显示属性的子集:

    [ScaffoldColumn(false)]
    

        4
  •  0
  •   JaySharp13    14 年前

    创建一个自定义DataAnnotationAttribute,将ProductType作为参数。然后应用于要查看的相应属性。您可以通过为产品创建EditorTemplate来进一步扩展此功能,该产品将处理进一步的流程、表单元素的外观和感觉,或者对某些表单元素进行JQuery。

        5
  •  0
  •   Martin R-L    14 年前

    我已经复习了所有的答案,并且更彻底地思考了这个问题。我采取了这样的方法

    使用产品视图模型生成器,以及 从不同的视图模型 自动生成视图 (包括下拉列表和其他内容) 不是开箱的)?

    从我最初的问题。

    而不是使用 EditorFor/EditorForModel 开箱即用,我根据布拉德·威尔逊的想法制作了自己的定制模板 described in this post

    干巴巴的,简单的,显式的(虽然我希望我有一个动态语言不止一次,以减少代码和摆脱一些反射…)。