Over the last 4 years, JavaScript has been critical to the majority of the web applications that I have worked on; dealing with the logical organization of said files has always been a less-than-satisfactory experience until about 2 years ago when I began using the following techniques for a easier design-time experience.
Let's say I have a page named foo.aspx and I have JavaScript specific to it contained in a file - I name the .js file foo.aspx.js. Then, in a base class for the pages of the application, I have the following code:
1: protected override void OnLoad(EventArgs e)
2: {
3: base.OnLoad(e);
4: AttachPageSpecificJavaScriptFile();
5: }
6:
7: private void AttachPageSpecificJavaScriptFile()
8: {
9: var appRelativeVirtualPath = string.Format("{0}.js", TemplateControl.AppRelativeVirtualPath);
10: RegisterJavaScriptFile(appRelativeVirtualPath);
11: }
12:
13: protected void RegisterJavaScriptFile(string appRelativeVirtualPath)
14: {
15: if (JavaScriptFileExists(appRelativeVirtualPath))
16: {
17: string url = ResolveClientUrl(appRelativeVirtualPath);
18: ClientScript.RegisterClientScriptInclude(url, url);
19: }
20: }
Essentially, for each page in my application, the app will look for a *.aspx.js file that matches the name of the page (in our example, foo.aspx.js) and place, within the rendered page, a script tag referencing it.
Since every request to a given page would need to check to see whether or not an associated .js file existed, and considering the fact that checking with the file system each time would be somewhat costly, I have the following code take care of checking and then caching the results at the application level:
1: private Dictionary<string, bool> JavaScriptFileRegistry
3: get
4: {
5: var javaScriptFileRegistry = Application["JavaScriptFileRegistry"] as Dictionary<string, bool>;
6: if (javaScriptFileRegistry == null)
7: {
8: javaScriptFileRegistry = new Dictionary<string, bool>();
9: Application["JavaScriptFileRegistry"] = javaScriptFileRegistry;
10: }
11: return javaScriptFileRegistry;
12: }
13: }
14:
15: protected bool JavaScriptFileExists(string appRelativeVirtualPath)
17: var registry = JavaScriptFileRegistry;
18: if (registry.ContainsKey(appRelativeVirtualPath) == false)
19: {
20: registry.Add(appRelativeVirtualPath, File.Exists(Server.MapPath(appRelativeVirtualPath)));
21: }
22: return registry[appRelativeVirtualPath];
23: }
To complete this, I have a registry hack that will cause any *.aspx.js files to collapse underneath the *.aspx page in the solution explorer of Visual Studio (i.e. it will hide underneath the page, just like the *.aspx.cs file does). Depending on the version of Visual Studio you are using, the registry hack is different. Here are a couple that I use with Windows XP (I don't know if they differ for Vista because I don't use Vista) - copy each one into a text file and rename it with a .reg extension, then execute the file.
1: Windows Registry Editor Version 5.00
2: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Projects\{E24C65DC-7377-472b-9ABA-BC803B73C61A}\RelatedFiles\.aspx\.js]
3: @=""
2: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Projects\{E24C65DC-7377-472b-9ABA-BC803B73C61A}\RelatedFiles\.aspx\.js]
You will probably need to reboot your machine before these take effect. Also, the nesting will only take place for newly-added .js files, any that you have which are already named *.aspx.js can be nested by either re-adding them to the project or manually modifying the .csproj file's XML.
Anyway, that is how I do things and it really helps to keep things organized. I also do all of this for user controls (ascx files) - with the above, it should be simple enough to figure out how to do this for the user controls and ascx file extension.
Hope this helps someone!
Remember Me
a@href@title, b, blockquote@cite, i, strike, u
Disclaimer The opinions expressed herein are Jason Bunting's personal opinions, as they are presently constituted, and are subject to change and do not represent his employer's view in any way; feel free to disagree with him. Jason Bunting is not a doctor, and no advice/information presented on this website is intended to diagnose, treat or cure any disease. When you have health questions, always seek help from a qualified health practitioner or naturopathic physician. This information is provided as-is, without warranty, and is solely the opinion of Jason Bunting, whose opinions may differ from mainstream medical opinion.