7

应用程序是一个带有 RAZOR 视图引擎的 MVC3 应用程序。

这里使用的控制器是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”下。但是 View 引擎似乎只是不接受它。

但是,此处的Microsoft 文档指出,视图引擎确实在 Controller\DisplayTemplates 文件夹中查找以使用使用的 TemplateName 获取 VIEW。

4

3 回答 3

6

这似乎是 Display/EditorTemplates 的预期行为,大概是为了防止自定义显示模板中的意外无限递归,例如执行 (in Item.cshtml):

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

...这将无限显示Item.cshtmlDisplayTemplate。

显然,在您的示例中,您将项目/模型传递给不同的模板,因此它不会导致无限递归。但是,它似乎仍然被框架中的相同安全防护所捕获。不确定它是否会被归类为“错误”或只是“设计”?

这是DisplayFor/TemplateFor 助手中的检查:

// 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.cshtmlDisplayTemplate 并将项目/模型添加到VisitedObjects. 这意味着当Item.cshtml尝试显示另一个具有相同项目/模型的子模板时:

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

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

于 2012-05-03T21:56:04.133 回答
1

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

于 2012-05-03T21:13:59.907 回答
0

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

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

此外,您在主视图中的 DisplayFor() 是错误的。您不能以这种方式将 html 属性传递给 DisplayTemplates。

于 2012-05-03T21:09:42.497 回答