2014-10-31 121 views
5

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與頁面需要的類型參數相同。

回答

3

使用Partial在編輯模板insted的的@Html.EditorFor(m => m, ...)

@model SpecialChild 
@{ 
    ViewData["Extend"] = new MvcHtmlString("<span>SpecialChild is a </span>"); 
} 
@Html.Partial("~/Views/Shared/EditorTemplates/GeneralChild.cshtml", Model) 
+0

看來這個答案真的*爲*簡單:-) – chiccodoro 2014-10-31 15:03:59

+0

而且簡單就是最好的:) – py3r3str 2014-10-31 17:40:13

+1

對於它的價值,我都放在一起調查結果包括您對文章的幫助:http://darkroastjava.wordpress.com/2014/11/03/polymorph-razor-views/ – chiccodoro 2014-11-03 16:57:47

相關問題