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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5037580/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:54:02  来源:igfitidea点击:

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

asp.net-mvcasp.net-mvc-3razorasp.net-mvc-partialvieweditortemplates

提问by RPM1984

So, the title should speak for itself.

所以,标题应该不言自明。

To create re-usable components in ASP.NET MVC, we have 3 options (could be others i haven't mentioned):

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

Partial View:

部分视图:

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

Custom Editor Template:

自定义编辑器模板:

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

Custom Display Template:

自定义显示模板:

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

In terms of the actual View/HTML, all three implementations are identical:

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

@model WebApplications.Models.FooObject

<!-- Bunch of HTML -->

So, my question is - when/how do you decide which one of the three to use?

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

What i'm really looking for is a list of questions to ask yourself before creating one, for which the answers can be used to decide on which template to use.

我真正在寻找的是在创建一个问题之前要问自己的问题列表,这些问题的答案可用于决定使用哪个模板。

Here's the 2 things i have found better with EditorFor/DisplayFor:

这是我发现 EditorFor/DisplayFor 更好的两件事:

  1. They respect model hierarchies when rendering HTML helpers (e.g if you have a "Bar" object on your "Foo" model, the HTML elements for "Bar" will be rendered with "Foo.Bar.ElementName", whilst a partial will have "ElementName").

  2. More robust, e.g if you had a List<T>of something in your ViewModel, you could use @Html.DisplayFor(model => model.CollectionOfFoo), and MVC is smart enough to see it's a collection and render out the single display for each item (as opposed to a Partial, which would require an explicit for loop).

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

  2. 更健壮,例如,如果您List<T>的 ViewModel 中有一些东西,则可以使用@Html.DisplayFor(model => model.CollectionOfFoo),并且 MVC 足够聪明,可以看到它是一个集合并为每个项目呈现单个显示(而不是 Partial,这需要显式的环形)。

I've also heard DisplayFor renders a "read-only" template, but i don't understand that - couldn't i throw a form on there?

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

Can someone tell me some other reasons? Is there a list/article somewhere comparing the three?

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

采纳答案by marcind

EditorForvs DisplayForis simple. The semantics of the methods is to generate edit/insert and display/read only views (respectively). Use DisplayForwhen displaying data (i.e. when you generate divs and spans that contain the model values). Use EditorForwhen editing/inserting data (i.e. when you generate input tags inside a form).

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

The above methods are model-centric. This means that they will take the model metadata into account (for example you could annotate your model class with [UIHintAttribute]or [DisplayAttribute]and this would influence which template gets chosen to generate the UI for the model. They are also usually used for data models (i.e. models that represent rows in a database, etc)

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

On the other hand Partialis view-centric in that you are mostly concerned with choosing the correct partial view. The view doesn't necessarily need a model to function correctly. It can just have a common set of markup that gets reused throughout the site. Of course often times you want to affect the behavior of this partial in which case you might want to pass in an appropriate view model.

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

You did not ask about @Html.Actionwhich also deserves a mention here. You could think of it as a more powerful version of Partialin that it executes a controller child action and then renders a view (which is usually a partial view). This is important because the child action can execute additional business logic that does not belong in a partial view. For example it could represent a shopping cart component. The reason to use it is to avoid performing the shopping cart-related work in every controller in your application.

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

Ultimately the choice depends on what is it that you are modelling in your application. Also remember that you can mix and match. For example you could have a partial view that calls the EditorForhelper. It really depends on what your application is and how to factor it to encourage maximum code reuse while avoiding repetition.

最终选择取决于您在应用程序中建模的是什么。还要记住,您可以混合搭配。例如,您可以有一个调用EditorFor助手的局部视图。这实际上取决于您的应用程序是什么以及如何将其分解以鼓励最大程度的代码重用同时避免重复。

回答by Robert Levy

You certainly couldcustomize DisplayForto display an editable form. But the convention is for DisplayForto be readonlyand EditorForto be for editing. Sticking with the convention will ensure that no matter what you pass into DisplayFor, it will do the same type of thing.

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

回答by Ciaran Bruen

Just to give my 2c worth, our project is using a partial view with several jQuery tabs, and each tab rendering its fields with its own partial view. This worked fine until we added a feature whereby some of the tabs shared some common fields. Our first approach to this was to create another partial view with these common fields, but this got very clunky when using EditorFor and DropDownListFor to render fields and drop downs. In order to get the ids and names unique we had to render the fields with a prefix depending on the parent partial view that was rendering it:

只是为了给我 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>

This got pretty ugly so we decided to use Editor Templates instead, which worked out much cleaner. We added a new View Model with the common fields, added a matching Editor Template, and rendered the fields using the Editor Template from different parent views. The Editor Template correctly renders the ids and names.

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

So in short, a compelling reason for us to use Editor Templates was the need to render some common fields in multiple tabs. Partial views aren't designed for this but Editor Templates handle the scenario perfectly.

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

回答by jitendra joshi

Use _partialview approach if:

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

  1. View Centric Logic
  2. What to keep all _partialview related HTML in this view only. In the template method, you will have to keep some HTML outside the Template View like "Main Header or any outer border/settings.
  3. Want to render partial view with logic (From controller) using URL.Action("action","controller").
  1. 查看中心逻辑
  2. _partial仅在此视图中保留所有与视图相关的 HTML。在模板方法中,您必须在模板视图之外保留一些 HTML,例如“主标题或任何外边框/设置。
  3. 想要使用URL.Action("action","controller").

Reasons to use Template:

使用模板的原因:

  1. Want to remove ForEach(Iterator). Template is well enough to identify Model as a list type. It will do it automatically.
  2. Model Centric Logic. If multiple views are found in the same displayfor Template folder, then rendering will depend on Passed Model.
  1. 想删除ForEach(Iterator)。模板足以将模型识别为列表类型。它会自动完成。
  2. 以模型为中心的逻辑。如果在模板文件夹的同一个显示中发现多个视图,则渲染将取决于传递的模型。

回答by erhan355

Another difference that hasn't been mentioned so far is that a partialview doesn't add model prefixes while a template does Hereis the issue

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