Question

We are in the early stages of introducing Script# to our project and so far we like what we see. However, I am a little confused as to the best strategy for adding scripts to individual pages/views.

In short, our asp.net mvc project has many controllers, and many views. Each of these views offers different functionality for part of our application.

It seems that Script# does offer the ability to output many different scripts for different folders if you set it up that way, but I have seen a response elsewhere on StackOverflow suggesting that this approach is frowned upon.

The only other way I can see of having per page scripting is to have a method call on each view firing in the $(Document).Ready() calling off to a method in the script that matches the view name, or something similar. This would work but I don't really like the idea that much.

How do others handle this?

Was it helpful?

Solution

I believe there are two motivations (usually based on prior conversations on the topic)

  1. It is too painful to have a c# project per page.
  2. You want to minimize the amount of script loaded in each page.

To address #1, there used to be a solution where a single c# project could be compiled in bits to generate multiple scripts, but that is gone. The reason it is gone is it makes it very easy to have different semantics by virtue of the c# compiler compiling a full project at a time, and the script# compiling a part of the project at a time. However all is not lost - you have a couple of alternatives.

  • Customize the msbuild process - specifically change the csproj to call into the ScriptCompilerTask multiple times with subsets of code. You're taking on the responsibility of making sure each subset of code compiles sucessfully, because the validation provided by the c# compiler is less meaningful.

  • Use the Script# compiler API to write a custom msbuild task. You can see the implementation of the msbuild task in the script# repository in github [1] and base it off that... you may even look back in the history on the sources to see how the msbuild task used to provide this.

To address #2, it is far better to think about what are the meaningful sets of scripts depending on your app scenarios and load them that way rather than a strictly one specific script file per page (once you account for caching, http requests etc.).

So lets assume you have scripts for multiple pages combined into a single script. Now to address your question of loading just the right script given the page. Here is what I have done:

In my pages, I annotate the body tag as such:

<body id="editPage">

And in my script#, I have the following:

internal static class EditPage {

    static EditPage() {
        jQuery.OnDocumentReady(delegate() {
            if (Document.BodyElement.ID == "editPage") {
                // Code you want to run on editPage
            }
        });
    }
}

There are various ways to accomplish this, but you don't have to strictly write a little bit of code in every page to call the right API. Hopefully this gives some idea of alternatives that have all the logic self-contained in the script.

One of the samples in script# (see https://github.com/nikhilk/scriptsharp/blob/cc/samples/AroundMe/AroundMe/Page.cs#L38) does something similar to conditionally run code.

One nice side-effect of this is most of your code can be turned into internal classes, since the view never calls directly into the script. Rather the script adds behavior to the page in an unobtrusive manner. The benefit of course is vastly increased minimizability of your scripts.

[1] https://github.com/nikhilk/scriptsharp

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top