我正在尝试使用编辑器模板显示视图模型,该模板在应用基础对象编辑器模板之前将模型包装在字段集中.
我的看法:
@model Mvc3VanillaApplication.Models.ContactModel
@using (Html.BeginForm())
{
@Html.EditorForModel("Fieldset")
}
Run Code Online (Sandbox Code Playgroud)
使用fieldset模板(Views/Shared/EditorTemplates/Fieldset.cshtml):
<fieldset>
<legend>@ViewData.ModelMetadata.DisplayName</legend>
@Html.EditorForModel()
</fieldset>
Run Code Online (Sandbox Code Playgroud)
而这又为所有对象使用基本模板(Views/Shared/EditorTemplates/Object.cshtml):
@foreach (var prop in ViewData.ModelMetadata.Properties.Where(x =>
x.ShowForEdit && !x.IsComplexType && !ViewData.TemplateInfo.Visited(x)))
{
@Html.Label(prop.PropertyName, prop.DisplayName)
@Html.Editor(prop.PropertyName)
}
Run Code Online (Sandbox Code Playgroud)
无论如何,那是我的意图.问题是,当页面使用字段集和图例进行渲染时,不会应用对象模板,因此不会显示任何输入控件.
如果我将视图更改为不指定"Fieldset"模板,则使用Object模板呈现模型的属性,因此不能找到我的Object模板.
是否可以通过多个模板传递相同的模型?
对于它的价值,视图模型如下所示:
namespace Mvc3VanillaApplication.Models
{
[System.ComponentModel.DisplayName("Contact Info")]
public class ContactModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
我实现了你所拥有的,并且能够重现它.我设置了一个断点,Object.cshtml所以我可以检查它,并且当我使用fieldset模板时,我发现它甚至没有碰到对象模板.然后我逐步完成了fieldset模板,看到它正好调用模板,所以必须在代码中发生一些事情,阻止它显示对象模板.
我打开了MVC3源代码,搜索EditorForModel并找到了正确的函数.
public static MvcHtmlString EditorForModel(this HtmlHelper html) {
return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */));
}
Run Code Online (Sandbox Code Playgroud)
显然这不是它,所以我按下F12了TemplateHelpers.TemplateHelper,然后再一次在那里我按下F12单线呼叫,它带你到功能的肉.在这里,我发现了从第214行开始的这段代码TemplateHelpers.cs:
// Normally this shouldn't happen, unless someone writes their own custom Object templates which
// don't check to make sure that the object hasn't already been displayed
object visitedObjectsKey = metadata.Model ?? metadata.RealModelType;
if (html.ViewDataContainer.ViewData.TemplateInfo.VisitedObjects.Contains(visitedObjectsKey)) { // DDB #224750
return String.Empty;
}
Run Code Online (Sandbox Code Playgroud)
这些评论实际上在代码中,在这里我们有你的问题的答案:一个模型可以通过多个编辑器模板传递吗?,答案是没有*.
话虽这么说,这似乎是一个非常合理的用例,所以寻找替代方案可能是值得的.我怀疑一个模板化的剃刀代表会解决这个包装功能,所以我试了一下.
@{
Func<dynamic, object> fieldset = @<fieldset><legend>@ViewData.ModelMetadata.DisplayName</legend>@Html.EditorForModel()</fieldset>;
}
@using (Html.BeginForm())
{
//@Html.EditorForModel("Fieldset")
//@Html.EditorForModel()
@fieldset(Model)
}
Run Code Online (Sandbox Code Playgroud)
而且中提琴!有效!我将把它作为扩展(以及更多可重用)方法实现.这是一篇关于模板化剃刀代表的简短博文.
*从技术上讲,你可以重写这个函数并编译你自己的MVC3版本,但它可能比它的价值更麻烦.当我们发现当你定义了几百条路线时,函数很慢,我们试图在职业项目中这样做Html.ActionLink.其余的库存在签名问题,我们认为现在不值得花时间研究并维护未来的MVC版本.
| 归档时间: |
|
| 查看次数: |
2037 次 |
| 最近记录: |