关于ASP.NET MVC 3:ASP.NET MVC 3 – 部分vs显示模板与编辑器模板

ASP.NET MVC 3 - Partial vs Display Template vs Editor Template

所以,这个标题应该能说明问题。

要在ASP.NET MVC中创建可重用组件,我们有3个选项(可能是我没有提到的其他选项):

部分观点:

1
@Html.Partial(Model.Foo,"SomePartial")

自定义编辑器模板:

1
@Html.EditorFor(model => model.Foo)

自定义显示模板:

1
@Html.DisplayFor(model => model.Foo)

就实际视图/html而言,这三种实现都是相同的:

1
2
3
@model WebApplications.Models.FooObject

<!-- Bunch of HTML -->

所以,我的问题是-你什么时候/如何决定使用三种方法中的哪一种?

我真正要找的是在创建问题之前要问自己的一系列问题,答案可以用来决定使用哪个模板。

以下是我在editor for/displayfor中发现的两件更好的事情:

  • 在呈现HTML助手时,它们尊重模型层次结构(例如,如果"foo"模型上有"bar"对象,"bar"的HTML元素将以"foo.bar.elementname"呈现,而部分元素将以"elementname"呈现)。

  • 更强大的功能,例如,如果您的ViewModel中有某个东西的List,您可以使用@Html.DisplayFor(model => model.CollectionOfFoo),并且MVC足够聪明,可以看到它是一个集合,并为每个项目呈现单个显示(而不是部分显示,这需要显式for循环)。

  • 我也听说过Displayfor呈现"只读"模板,但我不明白这一点-我不能在上面扔一个表单吗?

    有人能告诉我其他的原因吗?是否有比较这三个的列表/文章?


    EditorForDisplayFor比较简单。方法的语义是分别生成编辑/插入和显示/只读视图。显示数据时使用DisplayFor(即生成包含模型值的div和rans时)。编辑/插入数据时(即在表单内生成输入标记时),使用EditorFor

    以上方法以模型为中心。这意味着它们将考虑模型元数据(例如,您可以用[UIHintAttribute][DisplayAttribute]注释您的模型类,这将影响选择哪个模板来为模型生成UI。它们通常也用于数据模型(即表示数据库中行的模型等)。

    另一方面,Partial是以视图为中心的,因为您最关心的是选择正确的局部视图。视图不一定需要模型才能正常工作。它可以有一组通用的标记,这些标记可以在整个站点中重用。当然,通常您希望影响此部分的行为,在这种情况下,您可能希望传递到适当的视图模型中。

    你没有问过@Html.Action,这里也值得一提。您可以把它看作是Partial的一个更强大的版本,因为它执行一个控制器子操作,然后呈现一个视图(通常是一个局部视图)。这很重要,因为子操作可以执行不属于部分视图的其他业务逻辑。例如,它可以表示购物车组件。使用它的原因是为了避免在应用程序中的每个控制器中执行与购物车相关的工作。

    最终,选择取决于您在应用程序中建模的内容。还要记住,你可以混搭。例如,您可以有一个局部视图来调用EditorFor助手。它实际上取决于您的应用程序是什么,以及如何考虑它,以鼓励最大限度地重用代码,同时避免重复。


    您当然可以自定义DisplayFor以显示可编辑的表单。但该公约要求DisplayFor作为readonlyEditorFor进行编辑。遵守公约将确保无论你通过什么途径进入DisplayFor,它都会做同样的事情。


    为了让我的2c值,我们的项目使用了一个带有几个jquery选项卡的局部视图,并且每个选项卡都用自己的局部视图呈现其字段。这很好地工作,直到我们添加了一个特性,其中一些选项卡共享一些公共字段。我们的第一个方法是用这些公共字段创建另一个局部视图,但是当使用editorfor和dropDownListfor呈现字段和下拉列表时,这变得非常笨拙。为了获得唯一的ID和名称,我们必须根据呈现字段的父部分视图使用前缀呈现字段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
        <fieldset>
            <label for="@(idPrefix).Frequency">Frequency<span style="color: #660000;"> *</span></label>

            <input name="@(idPrefix).Frequency"
                   id="@(idPrefix)_Frequency"
                   style="width: 50%;"
                   type="text"
                   value="@(defaultTimePoint.Frequency)"
                   data-bind="value: viewState.@(viewStatePrefix).RecurringTimepoints.Frequency"
                   data-val="true"
                   data-val-required="The Frequency field is required."
                   data-val-number="The field Frequency must be a number."
                   data-val-range-min="1"
                   data-val-range-max="24"
                   data-val-range="The field Frequency must be between 1 and 24."
                   data-val-ignore="true"/>

            @Html.ValidationMessage(idPrefix +".Frequency")

            ... etc

        </fieldset>

    这变得相当难看,所以我们决定使用编辑器模板,这样做更干净。我们添加了一个带有公共字段的新视图模型,添加了匹配的编辑器模板,并使用来自不同父视图的编辑器模板呈现了这些字段。编辑器模板正确地呈现ID和名称。

    因此,简而言之,我们使用编辑器模板的一个令人信服的原因是需要在多个选项卡中呈现一些公共字段。部分视图不是为此设计的,但是编辑器模板可以完美地处理场景。


    到目前为止还没有提到的另一个区别是,partialView不添加模型前缀,而模板添加模型前缀。这是问题所在


    在下列情况下,使用_partial视图方法:

  • 以视图为中心的逻辑
  • 只在该视图中保留所有与_partial视图相关的HTML。在模板方法中,您必须在模板视图之外保留一些HTML,如"主标题或任何外部边框/设置"。
  • 希望使用URL.Action("action","controller")使用逻辑(从控制器)呈现局部视图。
  • 使用模板的原因:

  • 要删除ForEach(Iterator)。模板足以将模型标识为列表类型。它会自动完成。
  • 以模型为中心的逻辑。如果在同一个displayfor template文件夹中找到多个视图,则渲染将取决于传递的模型。