2012-05-03 23 views
6

应用是用剃刀视图引擎的MVC3应用。控制器被这里使用为什么RazorViewEngine不能拿起我的DisplayTemplate?

是的TestController。 我正在使用嵌套视图。

基础视图(项目一览)是这样的,

//Listing.cshtml 
@model ItemsList 
@for (int i = 0; i < Model.Items.Count(); i++) 
    { 
     @Html.DisplayFor(x => x.Items[i], new { RowPosition = i}) 
} 

这里是项目

//Item.cshtml 
@model Item 
@Html.DisplayFor(x=>x.HeaderText) 
@Html.DisplayFor(x=>x, "ItemDetails") 

模板,这里是项目的视图详细

//ItemDetails.cshtml 
@model Item 
@Html.DisplayFor(x=>x.Description) 

所以,我试图将模型从ITEM模板传递给ITEMDETAILS模板。 ItemDetails.cshtml放置在“Views \ Test \ DisplayTemplates”下。事实上,我已经尝试将其放置在“Views \ Shared”文件夹以及“Views \ Shared \ DisplayTemplates”下。但视图引擎似乎只是不去捡起它。

但是微软的文档here指出视图引擎看起来在控制器\ DisplayTemplates文件夹来获取使用TEMPLATENAME使用的视图。

+1

它可能不是一个错误。请写一个更有用/相关的标题。 – 2012-05-03 20:38:12

+2

汤姆,我的问题是为什么视图引擎不选择视图。 ItemDetails的显示仅显示空白。没有例外。我如何调试视图引擎如何在幕后工作? – EagerToLearn

+1

永远不要低估良好的午睡力量 –

回答

5

这似乎是显示/ EditorTemplates预期的行为,可能是为了防止在自定义的显示模板偶然无限递归,比如做(在Item.cshtml):

@model Item 
@Html.DisplayFor(x => x) 

。 ..将无限显示Item.cshtml DisplayTemplate。

显然在你的例子中,你将项目/模型传递给不同的模板,所以它不会导致无限递归。但是,它似乎仍然被框架中的同一个保险柜所吸引。不确定它会被归类为“错误”还是“按设计”?

这是DisplayFor/TemplateFor helper检查:对父模板

// 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; 
} 

ViewData.TemplateInfo.VisitedObjects存储访问的对象/模型。当您运行:

@Html.DisplayFor(x => x.Items[i], new { RowPosition = i}) 

它使得你的Item.cshtml DisplayTemplate,并增加了项目/模型VisitedObjects。这意味着,当Item.cshtml尝试显示同一项目/模型的另一个子模板:

@Html.DisplayFor(x => x, "ItemDetails") 

项/模式已经在VisitedObjects,所以上面的if语句返回true,而不是渲染ItemDetails.cshtml它只是默默地返回/呈现空字符串。

+0

最近我遇到了这个“特性”,它引起了我无尽的恐慌。我认为MVC团队在这里犯了一个错误。返回一个空字符串给开发人员一个很好的印象,直到他们看到输出为止。这也使得找出发生的事情几乎是不可能的。至少,代码可能会抛出异常,提供行为解释并提醒开发人员注意问题。 –

1

首先,不使用for循环。 Display/EditorTemplates能够处理集合。

二,什么是ItemsList?它是如何定义的?如果它只是指定一种特定的集合类型,那么不要那样做。只需要一个List或者其他的东西(除非你需要特殊的项目处理,在这种情况下在你的集合类中实现IEnumerable)。然后,您将有一个ItemsList.cshtml或只是一个Item.cshtml如果转换到使用列表

此外,您DisplayFor()中的主要观点是错误的。您无法以这种方式将HTML属性传递给DisplayTemplates。

0

尝试使用@Html.RenderPartial("ItemDetails", item)

相关问题