11

添加到頁面的CSS 引用是有辦法的CSS引用從局部視圖添加到頁面,並讓他們在渲染頁面的<head>(所要求的HTML 4.01 spec)?從局部視圖

+0

您的問題已經回答了幾次已經,http://stackoverflow.com/questions/912755/include-javascript- file-in-partial-views&http://stackoverflow.com/questions/885990/linking-javascript-libraries-in-user-controls。我們在這種情況下討論css還是js並不重要。 – 2010-11-18 02:48:20

+0

@BurningIce - 你說得對,資源的類型並不重要。您鏈接到的問題具有相同的接受答案,這對部分視圖無效,因爲他們無法使用asp:內容控件(解析器錯誤消息:內容控件必須是內容頁面中的頂級控件或嵌套母版頁引用母版頁。)或者我錯過了什麼? – kristian 2010-11-18 03:24:34

+0

嗯有趣的一點。我想唯一真正的方法是將你的腳本/ css分成他們自己的部分視圖。然後渲染部分在頭部分的asp:Content中。這是我所能想到的。 – Chev 2010-11-18 07:48:04

回答

1

您可以使用HttpModule來操作響應HTML並將任何CSS /腳本引用移動到適當的位置。這並不理想,我也不確定性能的影響,但它似乎是在沒有(a)基於JavaScript的解決方案或(b)針對MVC原則的情況下解決問題的唯一方法。

1

您可以在JavaScript塊中將部分視圖加載到頭部的樣式中,但考慮到您可能希望頭部的JavaScript塊出於相同原因,這可能很愚蠢。

我最近發現了一些很酷的東西。您可以將部分視圖序列化爲一個字符串,並將其作爲JSON對象的一部分發送回客戶端。這使您可以傳遞其他參數以及視圖。

Returning a view as part of a JSON object

你可以抓住用jQuery和Ajax JSON對象,並把它裝載了局部視圖,然後又是JSON財產可能是你的風格塊。 JQuery可以檢查你是否返回了一個樣式塊,如果是,則將其放入頭部。

喜歡的東西:

$.ajax(
{ 
    url: "your/action/method", 
    data: { some: data }, 
    success: function(response) 
    { 
      $('#partialViewContainer).html(response.partialView); 
      if (response.styleBlock != null) 
       $('head').append(response.styleBlock); 
    } 
}); 
+0

良好的思維,這將工作,但它取決於用戶啓用了JavaScript(這是公平的,如果你正在加載腳本資源,但沒有太多的CSS。) – kristian 2010-11-18 03:33:59

0

另一種方法,這違背了MVC的原則是使用視圖模型,併到你的頁面的Init事件來設置所需的CSS/JavaScript的(即myViewModel.Css迴應。新增(「CSS」),並在你的腦袋上呈現您的視圖模型的CSS-集合的內容。

要做到這一點,你創建你的所有車型,從繼承的基礎視圖模型類,ALA

public class BaseViewModel 
{ 
    public string Css { get; set; } 
} 

在你的母版頁設定要使用此視圖模型

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<BaseViewModel>" %> 

和你的頭部分,你可以寫出來的CSS屬性的值現在

<head runat="server"> 
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title> 
    <link href="../../Content/Site.css" rel="stylesheet" type="text/css" /> 

    <%= Model.Css %> 
</head> 

,在您的局部視圖你需要有這樣的代碼,這是MVC

<script runat="server"> 
    protected override void OnInit(EventArgs e) 
    { 
     Model.Css = "hej"; 

     base.OnInit(e); 
    } 
</script> 
+0

即使OP沒有提及ajax請求的部分,這當然會起作用,只是作爲標準頁面請求的一部分。我想挑戰是讓它適用於局部視圖,無論是作爲單個請求的一部分調用,還是作爲ajax刷新(我不知道它是如何工作的,除非它通過javascript注入頭部) – 2010-11-18 13:23:52

+1

Yikes!我根本不喜歡這個。我寧願違反保留頭部部分樣式的協議,也不願意拋棄我的MVC應用程序中的問題。 – Chev 2010-11-18 21:16:27

4

您也可以使用Telerik的開源控件MVC和這樣做有點難看:

<%= Html.Telerik().StyleSheetRegistrar() 
        .DefaultGroup(group => group 
        .Add("stylesheet.css")); 
head部分

<%= Html.Telerik().ScriptRegistrar() 
        .DefaultGroup(group => group 
        .Add("script.js")); 
在你的頁面的botttom腳本部分

你可以在任何視圖或局部視圖上添加腳本,它們應該可以工作。

如果你不想使用該組件,你總是可以從那裏激發你自己,做一些更自定義的事情。

哦,在Telerik中,您還可以選擇合併和壓縮腳本。

+0

+1,我喜歡這個解決方案。雖然我很想知道Telerik如何做它的業務。我可能會去看看它。 – Chev 2010-11-18 21:18:20

0

只有啓用了JavaScript,以下才有效。這是我使用完全相同的場景中的小幫手你提到:

// standard method - renders as defined in as(cp)x file 
public static MvcHtmlString Css(this HtmlHelper html, string path) 
{ 
    return html.Css(path, false); 
} 
// override - to allow javascript to put css in head 
public static MvcHtmlString Css(this HtmlHelper html, 
           string path, 
           bool renderAsAjax) 
{ 
    var filePath = VirtualPathUtility.ToAbsolute(path); 

    HttpContextBase context = html.ViewContext.HttpContext; 
    // don't add the file if it's already there 
    if (context.Items.Contains(filePath)) 
     return null; 

    // otherwise, add it to the context and put on page 
    // this of course only works for items going in via the current 
    // request and by this method 
    context.Items.Add(filePath, filePath); 

    // js and css function strings 
    const string jsHead = "<script type='text/javascript'>"; 
    const string jsFoot = "</script>"; 
    const string jsFunctionStt = "$(function(){"; 
    const string jsFunctionEnd = "});"; 
    string linkText = string.Format("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\"></link>", filePath); 
    string jsBody = string.Format("$('head').prepend('{0}');", linkText); 

    var sb = new StringBuilder(); 

    if (renderAsAjax) 
    { 
     // join it all up now 
     sb.Append(jsHead); 
     sb.AppendFormat("\r\n\t"); 
     sb.Append(jsFunctionStt); 
     sb.AppendFormat("\r\n\t\t"); 
     sb.Append(jsBody); 
     sb.AppendFormat("\r\n\t"); 
     sb.Append(jsFunctionEnd); 
     sb.AppendFormat("\r\n"); 
     sb.Append(jsFoot); 
    } 
    else 
    { 
     sb.Append(linkText); 
    } 

    return MvcHtmlString.Create(sb.ToString()); 
} 

用法:

<%=Html.Css("~/content/site.css", true) %> 

作品對我來說,壽如上所述,只有當啓用javascript,從而限制了其有效性一點。

5

如果您正在使用MVC3 &剃刀,給每個頁面項目添加到您的部分最好的辦法是: 1)從佈局頁 2)中調用RenderSection()聲明你的孩子中的相應部分網頁:

/Views/Shared/_Layout.cshtml:

<head> 
    <!-- ... Rest of your head section here ... -> 
    @RenderSection("HeadArea") 
</head> 

/Views/Entries/Index.cshtml:

@section HeadArea { 
    <link rel="Stylesheet" type="text/css" href="/Entries/Entries.css" /> 
} 

得到的HTML頁面,然後包括部分看起來像這樣:

<head> 
    <!-- ... Rest of your head section here ... -> 
    <link rel="Stylesheet" type="text/css" href="/Entries/Entries.css" /> 
<head> 
+0

您的解決方案幫助了我。謝謝! – 2011-05-07 09:13:36

+3

@Richard,你在這裏描述的不是針對OP的問題,他是在談論一個局部視圖,而'_Layout.cshtml'是一個佈局,而不是局部視圖(包含在Index.cshtml中的實例',並且想要將腳本直接渲染到_layout.cshtml的''標籤中。 – Shimmy 2012-11-13 06:55:31