EditorTemplates是偉大的,因爲它們允許在剃刀視圖中的某種「多態性」。但我缺少一個「磚」來完成多態性支持:EditorTemplate繼承 - 有沒有辦法
特殊類型的EditorTemplate是否可以繼承EditorTemplate的普通類型?
龍版本:
鑑於
class SpecialChild : GeneralChild { }
class Parent
{
GeneralChild AGeneralChild { get; set; }
SpecialChild ASpecialChild { get; set; }
}
和兩個編輯模板
@* GeneralChild.cshtml *@
@model GeneralChild
<span>GeneralChild</span>
@* SpecialChild.cshtml *@
@model SpecialChild
<span>SpecialChild is a</span> <span>GeneralChild</span>
我所得到的(這就是爲什麼我把它稱爲 「多態性」)是:
@* 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>"
也就是說,即使SpecialChild是GeneralChild並且有一個用於GeneralChild的模板,它也會自動選擇SpecialChild.cshtml模板。此外,如果我刪除該模板,它將回到GeneralChild.cshtml模板。換句話說,可以重用通用模板或在必要時覆蓋它。
現在對於我真的喜歡什麼:
我想重用GeneralChild.cshtml模板來定義SpecialChild.cshtml模板,就像在C#中的「基本方法」的號召。在僞代碼:
@* SpecialChild.cshtml *@
baseEditorFor()
@section SpecificPart
{
<span>SpecialChild is a </span>
}
@* GeneralChild.cshtml *@
@Html.RenderSection("SpecificPart") <span>GeneralChild</span>
是這樣的支持?
我迄今爲止嘗試:
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>")
})
不幸的是,@Html.EditorFor(m => m)
什麼都不做。這很有道理,因爲m => m
與原始m => m.ASpecialChild
的表達式不同。
我想我可以手工建立表達式樹,但後來我意識到編輯器模板中的類型參數(當然)與Index.cshtml中的不同。原始電話中的@Html
鍵入<Parent>
,而在模板中則爲<SpecialChild>
。
然後我嘗試另一種方法是我迄今爲止最接近:
中的索引。CSHTML我定義了一個剃鬚刀幫手:
@helper SpecialChildEditorFor(Expression<Func<Parent,SpecialChild>> expression)
{
@Html.EditorFor(
expression,
"GeneralChild",
new { Extend = new MvcHtmlString("<span>SpecialChild is a </span>") })
}
然後我把這個代替EditorFor
:
@SpecialChildEditorFor(m => m.ASpecialChild)
但是這當然缺乏的最初提到的優點全部 - 我不能簡單地放棄這一在EditorTemplates目錄中的片段,從而「覆蓋」GeneralChild.cshtml模板。此外,它需要明確調用(所以我們也失去了「多態性」)。更重要的是,剃刀助手與Index.cshtml頁面相關:*必須在使用它的頁面中定義。 *它依賴於expression
與頁面需要的類型參數相同。
看來這個答案真的*爲*簡單:-) – chiccodoro 2014-10-31 15:03:59
而且簡單就是最好的:) – py3r3str 2014-10-31 17:40:13
對於它的價值,我都放在一起調查結果包括您對文章的幫助:http://darkroastjava.wordpress.com/2014/11/03/polymorph-razor-views/ – chiccodoro 2014-11-03 16:57:47