EditorTemplates sind großartig, da sie eine Art von "Polymorphismus" in Rasierer Ansichten erlauben. Aber mir fehlt ein "Baustein", um die Polymorphismus-Unterstützung zu vervollständigen:EditorTemplate Vererbung - gibt es einen Weg
Kann ein EditorTemplate für einen speziellen Typ von der EditorTemplate für den allgemeinen Typ erben?
Lange Version:
Gegeben
class SpecialChild : GeneralChild { }
class Parent
{
GeneralChild AGeneralChild { get; set; }
SpecialChild ASpecialChild { get; set; }
}
und zwei Editor Vorlagen
@* GeneralChild.cshtml *@
@model GeneralChild
<span>GeneralChild</span>
@* SpecialChild.cshtml *@
@model SpecialChild
<span>SpecialChild is a</span> <span>GeneralChild</span>
Was ich (weshalb ich es "Polymorphismus" nennen) ist:
@* Index.cshtml *@
@Html.EditorFor(m => m.AGeneralChild)
// prints "<span>GeneralChild</span>", however
@Html.EditorFor(m => m.ASpecialChild)
// prints "<span>SpecialChild is a</span> <span>GeneralChild</span>"
Das heißt, obwohl SpecialChild ein GeneralChild ist und es eine Vorlage für GeneralChild gibt, wählt es automatisch die Vorlage SpecialChild.cshtml aus. Außerdem, wenn ich diese Vorlage entferne, fällt sie zurück auf die GeneralChild.cshtml Vorlage. Mit anderen Worten, es ist möglich, eine allgemeine Vorlage zu verwenden oder diese bei Bedarf zu überschreiben.
nun für das, was ich würde wirklich wie:
Ich mag würde die GeneralChild.cshtml Vorlage wiederzuverwenden die SpecialChild.cshtml Vorlage zu definieren, wie ein „Basismethode“ Aufruf in C#. In Pseudocode:
@* SpecialChild.cshtml *@
baseEditorFor()
@section SpecificPart
{
<span>SpecialChild is a </span>
}
@* GeneralChild.cshtml *@
@Html.RenderSection("SpecificPart") <span>GeneralChild</span>
Wird so etwas unterstützt?
Was ich bisher versucht:
GeneralChild.cshtml:
@model GeneralChild
@{
var extend = ViewData.ContainsKey("Extend")
? (MvcHtmlString)ViewData["Extend"]
: null;
}
@if (extend != null) { @extend }
<span>GeneralChild</span>
SpecificChild.cshtml:
@model SpecialChild
@Html.EditorFor(
m => m, // call editor for my model
"GeneralChild", // but call "base" instead of "this"
new
{
// Hand the HTML to insert as ViewData parameter
Extend = new MvcHtmlString("<span>SpecialChild is a </span>")
})
Leider @Html.EditorFor(m => m)
nichts tun. Das ist sinnvoll, weil m => m
nicht derselbe Ausdruck wie das Original m => m.ASpecialChild
ist.
Ich dachte, ich könnte den Ausdrucksbaum von Hand aufbauen, aber dann erkannte ich, dass die Typargumente innerhalb der Editorvorlage (natürlich) sich von denen in Index.cshtml unterscheiden. @Html
im ursprünglichen Anruf wird <Parent>
eingegeben, während es innerhalb der Vorlage <SpecialChild>
ist.
Dann versuchte ich einen anderen Ansatz, der in der Nähe ich so weit gekommen ist:
Innerhalb des Index.cshtml Ich definiere einen Rasierer Helfer:
@helper SpecialChildEditorFor(Expression<Func<Parent,SpecialChild>> expression)
{
@Html.EditorFor(
expression,
"GeneralChild",
new { Extend = new MvcHtmlString("<span>SpecialChild is a </span>") })
}
Dann rufe ich diese statt EditorFor
:
@SpecialChildEditorFor(m => m.ASpecialChild)
Aber natürlich diese nicht über die Gesamtheit der die eingangs erwähnten Vorteile - Das kann ich nicht einfach fallen lassen Snippet im EditorTemplates-Verzeichnis, wodurch die GeneralChild.cshtml-Vorlage "überschrieben" wird. Außerdem muss es explizit aufgerufen werden (also haben wir auch "Polymorphismus" verloren). Mehr noch, der Rasiermesserhelfer ist an die Index.cshtml-Seite gebunden: * Er muss innerhalb der Seite definiert werden, auf der er verwendet wird. * Es basiert auf expression
, um die gleichen Typargumente zu haben wie die, die die Seite benötigt.
Es scheint, dass die Antwort wirklich * ist * so einfach :-) – chiccodoro
Und einfach ist am besten :) – py3r3str
Für was es wert ist, habe ich alle zusammen die Ergebnisse einschließlich Ihrer Hilfe in einen Artikel: http://darkroastjava.wordpress.com/2014/11/03/polymorph-razor-views/ – chiccodoro