web-dev-qa-db-fra.com

Comment rendre une section dans une vue partielle dans MVC3?

Dans un projet MVC3, j'ai un fichier "_Layout.vbhtml" avec ce code

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

Ensuite, j'ai une vue partielle "ValidationScripts.vbhtml" dans le dossier partagé avec

@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

Si j'appelle la vue partielle depuis une vue comme celle-ci ... 

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

@Html.Partial("ValidationScripts")

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

la section "Scripts" n'est pas rendue sur la page et le code HTML de sortie est 

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

  </body>
</html>

Comment puis-je rendre la section dans la vue partielle?

25
Max

J'ai eu le même problème avec des scripts en double, j'ai donc créé deux méthodes d'extension:

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());
  }
}

Sur n'importe quelle vue ou vue partielle ou modèle d'affichage/d'édition, vous ajoutez simplement ce dont vous avez besoin:

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

Dans vos mises en page, vous le restituez où vous le souhaitez:

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

Le seul problème que vous pouvez avoir est l'ordre dans lequel les scripts sont rendus si vous devenez trop complexe. Si cela devient un problème, ajoutez simplement les scripts au bas de vos vues/modèles et inversez simplement l'ordre dans la méthode d'extension avant de les restituer.

46
Erik Philips

Vous ne pouvez pas utiliser de sections dans des vues partielles. Vous pouvez choisir des aides personnalisées comme mentionné ici .

6
VJAI

Je pense que vous devriez utiliser des aides pour cela http://weblogs.asp.net/scottgu/archive/2011/05/12/asp-net-mvc-3-and-the-helper-syntax-within-razor .aspx

Si vous pouvez mettre à niveau vers MVC4, vous pouvez utiliser la nouvelle fonctionnalité de groupement et de minification: http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification . Il est spécialement conçu pour aborder ce que vous essayez d’atteindre (y compris les scripts). 

Sinon, vous pouvez utiliser http://combres.codeplex.com/ avec MVC3

2
Zar Shardan

Si je comprends bien, vous avez une structure

  • Layout.cshtml
  • Vue - X
    • PartialView Y (appelé dans View-X)

alors vous devez définir le 

@section Script{ .... } dans View-X et PAS PartialView Y depuis View-X a son View.Layout défini sur Layout.cshtml

0
frictionlesspulley