72 votes

Inclure le fichier JavaScript dans les vues partielles

Je me demande ce que les meilleures pratiques, y compris pour les fichiers javascript à l'intérieur des vues partielles. Une fois rendu cela va finir comme un js à inclure la balise au milieu de ma page html. De mon point de vue ce n'est pas une belle façon de le faire. Ils appartiennent à la balise head et en tant que tel ne devrait pas empêcher le navigateur de rendu html d'un seul coup.

Un exemple: Je suis à l'aide de jquery picturegallery plugin à l'intérieur d'un 'PictureGallery' vue partielle que cette vision partielle sera utilisé sur plusieurs pages. Ce plugin ne doit être chargé lors de ce point de vue est utilisé et je ne veux pas avoir besoin de savoir quels plugins chaque vue partielle est à l'aide de...

Merci pour vos réponses.

29voto

Charlino Points 11217

Semble très similaire à cette question: Lier les Bibliothèques JavaScript dans les Contrôles Utilisateur

Je vais reposter ma réponse à cette question ici.

Je serais certainement vous déconseillons de les mettre à l'intérieur de partiels exactement pour la raison que vous mentionnez. Il y a une forte chance que l'on pourrait tirer dans deux partiels qui ont tous deux des références pour le même fichier js. Vous avez aussi l'impact sur les performances de chargement js avant de charger le reste de l'html.

Je ne sais pas à propos de les meilleures pratiques, mais j'ai choisi d'inclure commune, js fichiers à l'intérieur de la masterpage et puis de définir une distinct ContentPlaceHolder pour avoir un peu de js fichiers qui sont spécifiques d'un particulier ou d'un petit nombre de points de vue.

Voici un exemple de page maître - c'est assez explicite.

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<head runat="server">
    ... BLAH ...
    <asp:ContentPlaceHolder ID="AdditionalHead" runat="server" />
    ... BLAH ...
    <%= Html.CSSBlock("/styles/site.css") %>
    <%= Html.CSSBlock("/styles/ie6.css", 6) %>
    <%= Html.CSSBlock("/styles/ie7.css", 7) %>
    <asp:ContentPlaceHolder ID="AdditionalCSS" runat="server" />
</head>
<body>
    ... BLAH ...
    <%= Html.JSBlock("/scripts/jquery-1.3.2.js", "/scripts/jquery-1.3.2.min.js") %>
    <%= Html.JSBlock("/scripts/global.js", "/scripts/global.min.js") %>
    <asp:ContentPlaceHolder ID="AdditionalJS" runat="server" />
</body>

Html.CSSBlock Et Html.JSBlock sont bien évidemment mes propres extensions, mais encore une fois, ils sont explicites dans ce qu'ils font.

Puis en dire un Inscription.aspx vue j'aurais

<asp:Content ID="signUpContent" ContentPlaceHolderID="AdditionalJS" runat="server">
    <%= Html.JSBlock("/scripts/pages/account.signup.js", "/scripts/pages/account.signup.min.js") %>
</asp:Content>

HTHs, Charles

Ps. Voici un suivi de la question que j'avais posée sur les minifying et concaténation de fichiers js: Concaténer & Rapetisser JS à la volée OU au moment de la construction - ASP.NET MVC

EDIT: Comme l'a demandé sur mon autre réponse, mon implémentation .JSBlock(a, b) comme demandé

public static MvcHtmlString JSBlock(this HtmlHelper html, string fileName)
{
    return html.JSBlock(fileName, string.Empty);
}

public static MvcHtmlString JSBlock(this HtmlHelper html, string fileName, string releaseFileName)
{
    if (string.IsNullOrEmpty(fileName))
        throw new ArgumentNullException("fileName");

    string jsTag = string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>",
                                 html.MEDebugReleaseString(fileName, releaseFileName));

    return MvcHtmlString.Create(jsTag);
}

Et puis, là où la magie opère...

    public static MvcHtmlString MEDebugReleaseString(this HtmlHelper html, string debugString, string releaseString)
    {
        string toReturn = debugString;
#if DEBUG
#else
        if (!string.IsNullOrEmpty(releaseString))
            toReturn = releaseString;
#endif
        return MvcHtmlString.Create(toReturn);
    }

2voto

jhorback Points 565

La raison pour laquelle vous avez mis un script en bas de la page est de veiller à ce que le dom est chargé avant de commencer toute manipulation. Cela peut également être réalisé dans quelque chose comme le $(document).prêt(callback); méthode jQuery.

Je partage le point de vue de ne pas mettre le JavaScript intégré dans le html. Au lieu de cela j'ai utiliser un helper Html pour créer un div vide pour l'utiliser comme un serveur d'instruction. L'aide d'un sig est Html.ServerData(String name, Object data);

J'utilise cette ServerData méthode pour obtenir des instructions à partir du serveur vers le client. La balise div maintient propre et les "données" de l'attribut est valide html5.

Pour le loadScript instruction, je peut faire quelque chose comme ça dans mon ascx ou aspx:

<%= Html.ServerData("loadScript", new { url: "pathTo.js" }) %>

Ou ajouter un autre helper pour ce faire, ce qui ressemble un peu plus propre:

<%= Html.LoadScript("~/path/to.js") %>

La sortie html serait:

<div name="loadScript" data-server="codé chaîne json">

Ensuite, j'ai une méthode jQuery permettant de trouver n'importe quel serveur de données de la balise: $(containingElement).serverData("loadScript"); // retourne un jQuery comme matrice de la décodé objets json.

Le client peut ressembler à quelque chose comme ceci:

var script = $(containingelement").serverData("loadScript");
$.getScript(script.url, function () {
 // script a été chargé - peut faire des choses avec elle maintenant
});

Cette technique est idéal pour les contrôles de l'utilisateur ou des scripts qui doivent être chargés au sein de l'ajax le contenu chargé. La version que j'ai écrit, c'est un peu plus complexe de la manipulation de la mise en cache des scripts afin qu'ils ne charge qu'une fois par plein de chargement des pages et contiennent des rappels et jQuery déclencheurs de sorte que vous pouvez brancher dans il quand il est prêt.

Si quelqu'un est intéressé à la version complète de ce (à partir de MVC pour jQuery extension), je serais heureux de montrer cette technique plus en détail. Sinon, les espoirs qu'il donne à quelqu'un une nouvelle façon d'aborder ce problème délicat.

1voto

Peter Points 5678

Aujourd'hui, j'ai créé ma propre solution qui s'adapte le projet de loi parfaitement. Si il est bon ou pas, est pour vous de décider, mais pensé que je devrais partager de toute façon!

Ci-dessous mon HtmlExtensions classe qui permet de faire cela dans votre masterpage:

<%=Html.RenderJScripts() %>

Mon HtmlExtensions classe:

public static class HtmlExtensions
{
    private const string JSCRIPT_VIEWDATA = "__js";

    #region Javascript Inclusions

    public static void JScript(this HtmlHelper html, string scriptLocation)
    {
        html.JScript(scriptLocation, string.Empty);
    }

    public static void JScript(this HtmlHelper html, string scriptLocationDebug, string scriptLocationRelease)
    {
        if (string.IsNullOrEmpty(scriptLocationDebug))
            throw new ArgumentNullException("fileName");

        string jsTag = "<script type=\"text/javascript\" src=\"{0}\"></script>";

#if DEBUG
        jsTag = string.Format(jsTag, scriptLocationDebug);
#else
        jsTag = string.Format(jsTag, !string.IsNullOrEmpty(scriptLocationRelease) ? scriptLocationRelease : scriptLocationDebug);
#endif

        registerJScript(html, jsTag);
    }

    public static MvcHtmlString RenderJScripts(this HtmlHelper html)
    {
        List<string> jscripts = html.ViewContext.TempData[JSCRIPT_VIEWDATA] as List<string>;
        string result = string.Empty; ;
        if(jscripts != null)
        {
            result = string.Join("\r\n", jscripts);
        }
        return MvcHtmlString.Create(result);
    }

    private static void registerJScript(HtmlHelper html, string jsTag)
    {
        List<string> jscripts = html.ViewContext.TempData[JSCRIPT_VIEWDATA] as List<string>;
        if(jscripts == null) jscripts = new List<string>();

        if(!jscripts.Contains(jsTag))
            jscripts.Add(jsTag);

        html.ViewContext.TempData[JSCRIPT_VIEWDATA] = jscripts;
    }

    #endregion

}

Ce qui se passe?
La classe ci-dessus permettra de prolonger la HtmlHelper avec des méthodes pour ajouter des liens en javascript pour une collection qui est stockée par l' HtmlHelper.ViewContext.TempData de la collecte. À la fin de la masterpage j'ai mis l' <%=Html.RenderJScripts() %> qui boucle la jscripts de collecte à l'intérieur de l' HtmlHelper.ViewContext.TempData , et de rendre ces à la sortie.

Il y a un inconvénient cependant,.. Vous devez vous assurer de ne pas rendre les scripts avant que vous les avez ajoutés. Si vous voulez le faire pour des liens de css par exemple, ça ne marcherait pas parce que vous avez à les replacer dans l' <head> balise de votre page et le htmlhelper rendrait la sortie avant même que vous avez ajouté un lien.

0voto

Allen Rice Points 8899

Cela ressemble à une semblable (bien que pas entièrement) question. C’est une mauvaise habitude pour renvoyer des vues partielles qui contiennent javascript ?

0voto

Pita.O Points 1007

Ma préférence sera de créer une page plugin.master qui hérite de votre principal Site.master. L’idée est ce genre de choses vous ces plugins dans plugin.master et faire les pages 8 ou alors qui utiliseront cette vue partielle hérite de plugin.master.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X