ASP.NET MVC 3 - 部分vs显示模板与编辑器模板

RPM*_*984 302 asp.net-mvc asp.net-mvc-partialview editortemplates razor asp.net-mvc-3

所以,标题应该说明一切.

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

局部视图:

@Html.Partial(Model.Foo, "SomePartial")
Run Code Online (Sandbox Code Playgroud)

自定义编辑模板:

@Html.EditorFor(model => model.Foo)
Run Code Online (Sandbox Code Playgroud)

自定义显示模板:

@Html.DisplayFor(model => model.Foo)
Run Code Online (Sandbox Code Playgroud)

就实际的View/HTML而言,所有三种实现都是相同的:

@model WebApplications.Models.FooObject

<!-- Bunch of HTML -->
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是 - 你何时/如何决定使用三者中的哪一个?

我真正想要的是在创建问题之前要问自己的问题列表,其答案可用于决定使用哪个模板.

以下是我使用EditorFor/DisplayFor找到的2件更好的东西:

  1. 它们在呈现HTML帮助程序时尊重模型层次结构(例如,如果在"Foo"模型上有"Bar"对象,则"Bar"的HTML元素将使用"Foo.Bar.ElementName"呈现,而部分将具有"的ElementName").

  2. 更强大,例如,如果你List<T>在ViewModel中有一些东西,你可以使用@Html.DisplayFor(model => model.CollectionOfFoo),而MVC足够聪明,可以看到它是一个集合,并为每个项目渲染单个显示(而不是Partial,这需要一个明确的环).

我也听说DisplayFor呈现了一个"只读"模板,但我不明白 - 我不能在那里扔一个表格吗?

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

mar*_*ind 300

EditorForvs DisplayFor很简单.这些方法的语义是分别生成编辑/插入和显示/只读视图.DisplayFor在显示数据时使用(即,当您生成包含模型值的div和spans时).EditorFor编辑/插入数据时使用(即在表单内生成输入标签时).

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

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

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

最终,选择取决于您在应用程序中建模的内容.还记得你可以混搭.例如,您可以使用调用EditorFor帮助程序的部分视图.这实际上取决于您的应用程序是什么以及如何将其考虑在内以鼓励最大程度地重用代码,同时避免重复.

  • 这是一个很好的答案,正是我所寻找的.实际上,我很依赖你会来回答这个问题.:)谢谢马尔辛. (4认同)
  • @stormwild使用约定并在与它们相关的模型(/Views/DisplayTemplates/MyModel.cshtml)之后命名模板,或者用UIHint注释显式强制它. (3认同)

Rob*_*evy 15

您当然可以自定义DisplayFor以显示可编辑的表单.但该公约是DisplayForreadonlyEditorFor要进行编辑.坚持惯例将确保无论你传入什么DisplayFor,它都会做同样的事情.

  • @Joshua - 我认为有一些问题:"我也听说DisplayFor呈现了一个"只读"模板,但我不明白 - 我不能在那里扔一个表格吗? (19认同)
  • 我不认为对于何时应该使用显示模板与编辑器模板存在任何疑问/疑问.真正的问题似乎是你何时应该使用模板和部分.你的回答完全错过了这个. (2认同)

Cia*_*uen 13

为了给我的2c值,我们的项目使用带有几个jQuery选项卡的局部视图,每个选项卡使用自己的局部视图呈现其字段.这很好用,直到我们添加了一个功能,其中一些选项卡共享一些常见的字段.我们的第一个方法是使用这些常见字段创建另一个局部视图,但是当使用EditorFor和DropDownListFor来渲染字段和下拉时,这非常笨拙.为了获得唯一的id和名称,我们必须使用前缀渲染字段,具体取决于呈现它的父部分视图:

    <div id="div-@(idPrefix)2" class="toHide-@(idPrefix)" style="display:none">
    <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>
</div>
Run Code Online (Sandbox Code Playgroud)

这非常难看,所以我们决定使用编辑器模板,这样做得更清晰.我们添加了一个带有公共字段的新视图模型,添加了匹配的编辑器模板,并使用不同父视图中的编辑器模板渲染了字段.编辑器模板正确呈现ID和名称.

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