2009-06-30 5 views
6

ProblèmeWebForms: dynamique (ou absolue) des balises script dans MasterPages

Lorsque vous travaillez avec MasterPages, une irritation commune je rencontre est que les balises de script dans le maître sont liés à la page consommatrice. Par exemple, votre JavaScript peut fonctionner si votre page consommatrice est à la racine de votre application, mais lorsque vous placez une autre page dans un sous-dossier, le chemin relatif est interrompu et le JavaScript n'est pas trouvé. Et il n'y a pas moyen d'utiliser des chemins absolus dont je suis conscient dans ce cas.

Cette dernière fois, j'ai décidé de vraiment attaquer cela et de trouver une bonne solution.

Solutions proposées

j'ai essayé une stratégie qui tournait autour de l'appel ClientScriptManager.RegisterClientScriptInclude à Page_Load, mais cela ne semble pas rendre quelque chose (accordé, ma compréhension de la plomberie connexe est incomplète).

J'ai essayé une autre qui ressemblait à ceci:

<script language="javascript" src='<%= ResolveClientUrl("~/js/ddnmenu.js") %>' type="text/javascript"></script> 

... Mais ce déclenche une exception: la collection Controls ne peut pas être modifié car le contrôle contient des blocs de code.

de travail (mais un peu fugly) Code

Alors, ce que je fini par aller avec est un contrôle Literal dans la tête où je rends le approprié Html:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
    Me.SetupLiteralScriptsTag() 
End Sub 

Private Sub SetupLiteralScriptsTag() 
    'Build the script tags to import our JavaScript 
    Dim Builder As New StringBuilder 

    Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/jquery-1.3.2.min.js"))) 
    Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/jquery.corners.min.js"))) 
    Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/bg.pos.js"))) 
    Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/moonstone.js"))) 

    Me.LiteralScriptTags.Text = Builder.ToString 
End Sub 

Cela fonctionne, mais Je ne suis pas en feu à ce sujet, car il semble que ce soit un peu trop d'une solution de contournement pour ce qui doit être un problème extrêmement commun. Y a-t-il un meilleur moyen?

Répondre

3

J'utilise partout la syntaxe relative à l'application. Il a l'inconvénient que si vous changez le nom/chemin de l'application, alors vous avez beaucoup de travail à faire pour mettre à jour toutes vos URL.

< script language = "javascript" src = "/ MyAppName/includes/MyJavascriptFile.js">

ou si vous travaillez sur l'application racine, puis:

< script language = "javascript "src ="/Includes/MyJavascriptFile.js ">

+0

Au moins le travail est minimisé dans le scénario des pages maîtres. C'est incroyable que je ne savais pas que vous pouviez le faire de cette façon ... Je travaille sur des applications web depuis très longtemps! –

+0

J'ai accepté celui-ci au lieu de la réponse de M4N puisque c'est le plus simple. Vous pouvez l'utiliser sans introduire de nouveaux concepts dans votre projet ... Bien que j'utilise ScriptManager pour ça maintenant. –

0

Vous pouvez toujours référencer votre script depuis la racine. IE:

<script language="javascript" src="/scripts/file.js"></script> 

N'importe quelle page de votre application obtiendrait alors correctement le javascript.

En outre, puisque vous travaillez avec ASP.NET, vous pouvez utiliser le caractère "~" pour fournir des chemins relatifs à l'application.Voir Rick Strahl's article on ASP.NET paths for more info.

+0

Le tilde ne fonctionne que dans les contrôles du serveur. J'aimerais l'utiliser ici cependant. –

7

Vous pouvez ajouter un ScriptManager à la page principale et inclure les fichiers javascript via que:

<asp:ScriptManager ...> 
    <Scripts> 
    <asp:ScriptReference Path="~/js/ddnmenu.js" /> 
    </Scripts> 
</asp:ScriptManager> 

Un autre avantage de cette approche est que vous pouvez ajouter un contrôle ScriptManagerProxy à vos pages de contenu (et commandes utilisateur) pour inclure des scripts supplémentaires.

Certains remplacements tiers pour ASP: ScriptManager (par exemple de la suite de RadControls de telerik ou du Ajax control toolkit) offrent encore plus de fonctionnalités, telles que la fusion tous les scripts java fichiers inclus dans un seul fichier (réduisant ainsi le nombre requis HTTP demandes de chargement d'une page).

Modifier: en utilisant un ScriptManager a d'autres avantages par exemple vous pouvez envoyer des versions de débogage ou de version de vos scripts au navigateur, ou des scripts dépendant de la culture, etc. Jetez un oeil à this page in MSDN pour un aperçu.

+0

J'aime cette réponse. J'aimerais pouvoir les accepter tous les deux. –

+0

Alors acceptez simplement le mien ;-) - non sérieusement, acceptez la réponse qui vous a le plus aidé. – M4N

1

J'utilise Page.resolveUrl("~/somefile.js");

fonctionne comme un champion

0

La collection Controls ne peut pas être modifié car le contrôle contient des blocs de code

Cette erreur semble familier. This page aidé quand je fouillais mon chemin à travers celui-ci

Questions connexes