2009-05-20 5 views
8

J'ai utilisé ASP.NET MVC pendant environ six mois et j'ai consulté l'exemple de Nerd Dinner créé par ces gars de Microsoft. Une chose que j'ai remarqué qu'ils ont fait en activant AJAX pour RSVP pour un dîner, est mis les références JavaScript dans le contrôle utilisateur utilisé pour RSVPing.
(FICHIER: RSVPStatus.ascx)Liaison de bibliothèques JavaScript dans les contrôles utilisateur

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NerdDinner.Models.Dinner>" %> 

<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script> 
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>  

Cela ne me semble pas juste, car il y a une très bonne chance, je serais en utilisant ces mêmes bibliothèques ailleurs, comme l'authentification d'ouverture de session. De plus, si je change les versions de script, je dois rechercher toutes les références aux bibliothèques.

Donc, je demande si ma pensée est correcte et ces références devraient être dans un endroit plus central comme la page maître?

S'il vous plaît laissez-moi savoir ce que la meilleure pratique est pour cela et avantages et inconvénients le cas échéant.

+1

Je les ai mis là-dedans parce que je seulement en utilisant le partiel une fois. Si je l'utilisais deux fois, je le déplacerais. Pas besoin de construire pour un usage multiple si je ne l'utilise pas plusieurs fois. –

+1

@Scott, où les déplaceriez-vous? Je suppose que c'est vraiment la question ici. Si vous n'en avez pas besoin sur toutes les pages d'affichage, il semble inutile de les inclure sur la page maître. –

Répondre

7

Je déconseille clairement de les mettre à l'intérieur partials pour exactement la raison que vous mentionnez. Il y a de fortes chances qu'une vue puisse contenir deux partiels ayant tous deux des références au même fichier js. Vous avez également obtenu le coup de performance de chargement de js avant de charger le reste du code HTML. Je ne connais pas les bonnes pratiques mais je choisis d'inclure tous les fichiers js courants dans la page maître, puis de définir un ContentPlaceHolder distinct pour certains fichiers js supplémentaires spécifiques à un nombre de vues particulier ou réduit.

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 & Html.JSBlock sont évidemment mes propres extensions mais encore une fois, ils sont explicites dans ce qu'ils font.

Puis, par exemple une vue SignUp.aspx 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. Je suis d'accord avec Andrew en disant que tout JS commun qui est défini directement à l'intérieur de la page maître doit être concaténé et minifié.

EDIT: Ma mise en œuvre de .JSBlock (a, b) comme l'a 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 où la magie se produit ...

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); 
    } 
+0

Très bien, merci pour votre réponse, quelle est une bonne approche pour minimiser les fichiers js dans le monde ASP.NET MVC? – Brettski

+0

Bonne question ... Je suis un peu paresseux en ce moment et je viens de lancer un fichier bat dans le cadre de la construction qui minimise tous mes js. Le fichier jsmin.exe peut être trouvé ici http://www.crockford.com/javascript/jsmin.html - il y a aussi du code C# là-bas donc vous pouvez lancer votre propre application minifiy. Je serais intéressé à entendre comment quelqu'un concatène ET/OU les minimise à la volée OU au moment de la construction. – Charlino

+0

Je viens d'ouvrir une autre question pour répondre à ce qui est une bonne approche pour concaténer et réduire les fichiers JS (& CSS) - http://stackoverflow.com/questions/890561/concatenate-minify-js-on-the-fly- ou-at-build-time-asp-net-mvc – Charlino

0

Dans mon site Web, www.trailbehind.com, nous avons un ensemble de fichiers javascript qui appartiennent à toutes les pages. Et puis certaines pages incluent des bibliothèques supplémentaires.

Pour les fichiers JS que toutes les pages utilisent (il y a quelques dizaines de fichiers), nous les concaténons et les minimisons lors de la construction.

Il existe un indicateur dans notre fichier de paramètres indiquant s'il faut utiliser le javascript concaténé ou les fichiers séparés sur build. Ceci est critique afin que vous puissiez déboguer le javascript sur le développement, mais utilisez le petit javascript sur un seul fichier en production.

Voici notre code python pour combiner et rapetisser:

 
import os 
import thetrailbehind.lib.jsmin as jsmin 

JS_FILES = [ 'lib/json2.js', 
       'lib/markermanager.js', 
       'lib/labeledmarker.js', 
       'lib/rsh/rsh.js', 
       'lib/showdown.js', 
       'lib/yui.js', 
       'lib/dragzoom.js', 
       'gen/attribute_data.js', 
       'gen/national-parks.js', 
       'Widgets/CommentsWidget.js', 
       'Widgets/Search.js', 
       'Widgets/MenuWidget.js', 
       'Widgets/PhotoWidget.js', 
       'Widgets/ReportList.js', 
       'Widgets/help.js', 
       'attributes.js', 
       'rsh.js', 
       'map.js', 
       'mapcontrols.js', 
       'markers.js', 
       'amazon.js', 
       'plan_trip.js', 
       'init.js',] 


def concat(files, base_path, all_file, all_file_min): 
    if os.path.exists(base_path + all_file): 
    lasttime = os.path.getmtime(base_path + all_file) 
    else: 
    lasttime = 0 
    out_of_date = False 
    for file in files: 
    if os.path.getmtime(base_path + file) > lasttime: 
     out_of_date = True 
     break 
    if out_of_date: 
    outfile = open(base_path + all_file, 'w') 
    for file in files: 
     outfile.write(open(base_path + file).read()) 
     outfile.write("\n") 
    outfile.close() 

    alljs = open(base_path + all_file) 
    allminjs = open(base_path + all_file_min, "w+") 
    jsmin.JavascriptMinify().minify(alljs, allminjs) 
    alljs.close() 
    allminjs.close() 



def main(): 
    concat(JS_FILES, '/home/wibge/thetrailbehind/media/javascript/', 'gen/all.js', 'gen/all.min.js') 


if __name__ == "__main__": 
    main() 

Et voici le modèle Django/HTML où nous allumons:

 
{% if use_all_js %} 
    script type=text/javascript src=/site_media/javascript/gen/all.min.js> 
{% else %} 
    script type="text/javascript" src="/site_media/javascript/rsh.js"> 
    script type="text/javascript" src="/site_media/javascript/amazon.js"> 
    script type="text/javascript" src="/site_media/javascript/map.js"> 
    A BUNCH OF SEPARATE INCLUDES...etc 
{% endif %} 
Questions connexes