23

In un progetto MVC3, ho un file "_Layout.vbhtml" con questo codiceCome eseguire il rendering di una sezione in una vista parziale in MVC3?

<!DOCTYPE html> 
<html> 
    <head> 
    </head> 
    <body> 
    ... 
    <script src="@Url.Content("~/Scripts/jquery-1.8.2.min.js")"></script> 
    @RenderSection("Scripts", false) 
    </body> 
</html> 

Poi, ho una vista parziale "ValidationScripts.vbhtml" nella cartella condivisa con

@Section Scripts 
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script> 
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script> 
    <script src="@Url.Content("~/Scripts/jquery.validate.fix.js")"></script> 
    <script src="@Url.Content("~/Scripts/localization/messages_de.js")"></script>  
End Section 

Se io chiamo la Vista parziale da una vista come questa ...

@ModelType MvcExample.MyModel 
@Code 
    ViewData("Title") = "Test" 
End Code 

@Html.Partial("ValidationScripts") 

<h2>Just a Test</h2> 
... 

la sezione "script" non è reso sulla pagina, e l'output HTML è

<!DOCTYPE html> 
<html> 
    <head> 
    </head> 
    <body> 
    ... 
    <script src="@Url.Content("~/Scripts/jquery-1.8.2.min.js")"></script> 

    </body> 
</html> 

Come è possibile eseguire il rendering della sezione nella vista parziale?

risposta

45

Ho avuto lo stesso problema in cima script duplicati, così ho creato un paio di metodi di estensione:

public static class HtmlHelperExtensions 
{ 
    private const string _jSViewDataName = "RenderJavaScript"; 
    private const string _styleViewDataName = "RenderStyle"; 

    public static void AddJavaScript(this HtmlHelper htmlHelper, 
            string scriptURL) 
    { 
    List<string> scriptList = htmlHelper.ViewContext.HttpContext 
     .Items[HtmlHelperExtensions._jSViewDataName] as List<string>; 
    if (scriptList != null) 
    { 
     if (!scriptList.Contains(scriptURL)) 
     { 
     scriptList.Add(scriptURL); 
     } 
    } 
    else 
    { 
     scriptList = new List<string>(); 
     scriptList.Add(scriptURL); 
     htmlHelper.ViewContext.HttpContext 
     .Items.Add(HtmlHelperExtensions._jSViewDataName, scriptList); 
    } 
    } 

    public static MvcHtmlString RenderJavaScripts(this HtmlHelper HtmlHelper) 
    { 
    StringBuilder result = new StringBuilder(); 

    List<string> scriptList = HtmlHelper.ViewContext.HttpContext 
     .Items[HtmlHelperExtensions._jSViewDataName] as List<string>; 
    if (scriptList != null) 
    { 
     foreach (string script in scriptList) 
     { 
     result.AppendLine(string.Format(
      "<script type=\"text/javascript\" src=\"{0}\"></script>", 
      script)); 
     } 
    } 

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

    public static void AddStyle(this HtmlHelper htmlHelper, string styleURL) 
    { 
    List<string> styleList = htmlHelper.ViewContext.HttpContext 
     .Items[HtmlHelperExtensions._styleViewDataName] as List<string>; 

    if (styleList != null) 
    { 
    if (!styleList.Contains(styleURL)) 
    { 
     styleList.Add(styleURL); 
    } 
    } 
    else 
    { 
    styleList = new List<string>(); 
    styleList.Add(styleURL); 
    htmlHelper.ViewContext.HttpContext 
     .Items.Add(HtmlHelperExtensions._styleViewDataName, styleList); 
    } 
} 

public static MvcHtmlString RenderStyles(this HtmlHelper htmlHelper) 
{ 
    StringBuilder result = new StringBuilder(); 

    List<string> styleList = htmlHelper.ViewContext.HttpContext 
    .Items[HtmlHelperExtensions._styleViewDataName] as List<string>; 

    if (styleList != null) 
    { 
    foreach (string script in styleList) 
    { 
     result.AppendLine(string.Format(
     "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />", 
     script)); 
    } 
    } 

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

in ogni caso o di vista parziale o Mostra/Modifica modello è sufficiente aggiungere quello che vi serve:

@{ 
    Html.AddJavaScript("http://cdn.jquerytools.org/1.2.7/full/jquery.tools.min.js"); 
} 

Nel tuo layout si rendono dove vuoi:

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
    @Html.RenderStyles() 
    @Html.RenderJavascripts() 

L'onl Il problema che potresti avere è l'ordine in cui gli script vengono renderizzati se arrivi a complessi. Se questo diventa un problema, è sufficiente aggiungere gli script nella parte inferiore delle viste/modelli e semplicemente invertire l'ordine nel metodo di estensione prima di renderli.

+0

Meravigliose estensioni !!!! – Max

+2

Chiunque riveda questo usando MVC 4 (o superiore), dovresti probabilmente considerare l'uso di [Bundle Invece] (http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification). –

+0

Questo non funzionerà se si chiama il parziale nel file di layout. Html.AddJavaScript è già in esecuzione. – LiverpoolsNumber9

2

penso che si dovrebbe utilizzare aiutanti per questo http://weblogs.asp.net/scottgu/archive/2011/05/12/asp-net-mvc-3-and-the-helper-syntax-within-razor.aspx

Se è possibile effettuare l'aggiornamento a MVC4 è possibile utilizzare il nuovo accorpamento e minification caratteristica: http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification. È progettato specificamente per indirizzare ciò che stai cercando di ottenere (compresi gli script).

In alternativa è possibile utilizzare http://combres.codeplex.com/ con MVC3

+0

Potete per favore elaborare su come aggiungere script utilizzando '@ Helper'? – Shimmy

0

Se ho capito bene si dispone di una struttura

  • Layout.cshtml
  • View - X
    • PartialView Y (chiamato all'interno View-X)

allora avete bisogno di definire il

@section Script{ .... } nel View-X e NON PartialView Y dal View-X ha il suo View.Layout insieme a Layout.cshtml

+0

Ovviamente, posso aggiungere la sezione "Script" manualmente in qualsiasi vista. Tuttavia, se voglio raggruppare tutti i tag dello script in un posto e riutilizzarlo nelle Visualizzazioni, come posso farlo? – Max

+0

si potrebbe semplicemente rendere il partial nel layout stesso se gli script sono usati da tutte le viste che usano quel layout OPPURE se si deve fare riferimento al layout nel partial! Se vuoi andare su quella strada, puoi provare l'ereditarietà nei layout in cui il layout utilizzato dal partial restituisce il resto del materiale vuoto. Ha senso ? – frictionlesspulley

+0

Cosa? :) Sì, posso seguire quella strada, ma penso che i metodi di estensione di @ Erik siano più utili. – Max

5

Non è possibile utilizzare le sezioni in viste parziali Puoi andare per aiutanti personalizzati come indicato nello here.

+0

link utile, grazie. – Max

0

tutto questo era una grande informazione, tuttavia se si guarda il suo codice originale, la sezione è in maiuscolo quindi non viene riconosciuto.

dovrebbe essere @section blahblah non @Section