2014-10-31 71 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

相关问题