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