我一直试图组织我的观点,以优化加载时间,有css的头部和脚本在身体的末尾。
为此,我创建了三个内容占位符的主页:样式、主要内容和脚本。
按照(已实现)的目标,当我使用主视图呈现单个视图时,可以将所有共享组件和特定页面组件整理到呈现页面中各自的位置。当我尝试绘制一个主细节模型时,困难就出现了。
请考虑以下几点:
我有一个主细节模型,比如OrderItems和Order的视图以及OrderItems的视图。在努力干,不要重复我自己(呵呵!))我希望在Order视图中部分呈现OrderItems列表视图,并仍然实现正确的元素布局,即:将任何特定的css呈现到头部的内容占位符中,将内容呈现到主内容占位符中,脚本呈现到正文底部的脚本内容占位符中。
我目前有一个讨厌的黑客,但我想知道是否有一个更干净的方式这样做。
我的当前hack相当于sql交叉联接和where子句,因为我在order视图的每个内容占位符中执行orderitems视图的部分呈现,并将该占位符的名称注入视图数据。在orderitems视图中,如果占位符名称与目标占位符不相等,我返回那里,只有css被呈现到css位置占位符等。为了重新描述它,我在父类中呈现子元素三次,而在子元素中,我为每个呈现返回一个不同的内容部分。
闻起来怪怪的,而且不太优雅,因为孩子必须知道它正在被渲染等等。
我的下一个想法是尝试拦截ViewPage的一个副本,并使用SetRenderMethodDelegate来控制呈现,只在目标内容占位符控件上调用render,但这一点非常复杂。
谁能建议一种更好的方法来维护代码重用和最佳html输出?
一些示例代码:
<%@ Master Language="C#" ... %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Master-Detail</title>
<!--common styles-->
<link type="text/css" href="my.css" rel="stylesheet" />
<asp:ContentPlaceHolder ID="Styles" runat="server" ></asp:ContentPlaceHolder>
</head>
<body>
<!--common markup-->
<h2>Master Markup</h2>
<asp:ContentPlaceHolder ID="mainContent" runat="server"></asp:ContentPlaceHolder>
<!--common scripts-->
<script type="text/javascript" src="/scripts/my.js"></script>
<asp:ContentPlaceHolder ID="Scripts" runat="server"></asp:ContentPlaceHolder>
</body>
</html>订单视图
<%@ Page Title="Order" Language="C#" MasterPageFile="~/Views/Shared/my.Master" ... %>
<asp:Content ContentPlaceHolderID="Styles" runat="server">
<style type="text/css">
/*order styles*/
</style>
<%
var partialContext = this.Html.GetViewContext("OrderDetails", "List", this.ViewData.Model.Items, this.ViewData);
partialContext.RenderContentPlaceHolder("Styles");
%>
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<h3>Order Markup</h3>
<%
var partialContext = this.Html.GetViewContext("OrderDetails", "List", this.ViewData.Model.Items, this.ViewData);
partialContext.RenderContentPlaceHolder("MainContent");
%>
</asp:Content>
<asp:Content ContentPlaceHolderID="Scripts" runat="server">
<script type="text/javascript">
/*order specific script*/
</script>
<%
var partialContext = this.Html.GetViewContext("OrderDetails", "List", this.ViewData.Model.Items, this.ViewData);
partialContext.RenderContentPlaceHolder("Scripts");
%>
</asp:Content>订购项目视图:
<%@ Page Title="OrderItems" Language="C#" MasterPageFile="my.aspx" ... %>
<asp:Content ID="Content2" ContentPlaceHolderID="Styles" runat="server">
<% if (ViewData["placeHolderName"] != null && ViewData["placeHolderName"].ToString().ToLower() != "styles")
return; %>
<style type="text/css">
/*OrderItems style*/
</style>
</asp:Content>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<% if (ViewData["placeHolderName"] != null && ViewData["placeHolderName"].ToString().ToLower() != "maincontent")
return; %>
<h4>Order Items MarkUp</h4>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="Scripts" runat="server">
<% if (ViewData["placeHolderName"] != null && ViewData["placeHolderName"].ToString().ToLower() != "scripts")
return; %>
<script type="text/javascript">
/*Order Items script*/
</script>
</asp:Content>其中有几种扩展方法:
public static ViewContext GetViewContext(this HtmlHelper htmlHelper, String controller, String viewName, Object model, ViewDataDictionary viewData)
{
var routeData = new System.Web.Routing.RouteData();
routeData.Values["controller"] = controller;
var controllerContext = new ControllerContext(htmlHelper.ViewContext.HttpContext, routeData, htmlHelper.ViewContext.Controller);
var viewEngineResult = ViewEngines.Engines.FindView(controllerContext, viewName, "Partial");
var viewData2 = new ViewDataDictionary(viewData);
viewData2.Model = model;
var viewContext = new ViewContext(controllerContext, viewEngineResult.View, viewData2, htmlHelper.ViewContext.TempData, htmlHelper.ViewContext.Writer);
return viewContext;
}
public static void RenderContentPlaceHolder(this ViewContext context, String placeHolderName)
{
context.ViewData["placeHolderName"] = placeHolderName;
context.View.Render(context, context.Writer);
context.ViewData.Remove("placeHolderName");
}发布于 2010-11-01 02:45:40
请看一下不久前提出的类似问题:
How can I include css files from an MVC partial control?
特别是被接受的答案中提供的链接非常有趣:
http://www.codeproject.com/Articles/38542/Include-Stylesheets-and-Scripts-From-A-WebControl-.aspx
编辑:您可以在这里找到同一作者的另一篇博客文章,为MVC 2更新:http://somewebguy.wordpress.com/2010/04/06/adding-stylesheets-scripts-in-asp-net-mvc2/
https://stackoverflow.com/questions/3800721
复制相似问题