Please suggest a strategy for serving JavaScript containing server-side code.

I think this is a common scenario. I have a view where I use HtmlHelper to generate some HTML elements, I also have a helper extension that allows me to get the generated element identifier so that I can use it in JavaScript (e.g. jQuery):

$('#@Html.FieldIdFor(model => model.Name)').autocomplete({ 

Or, when I do Ajax, I am building a URL string from UrlHelper, again using the server side code to put some elements on the client side on the page:

 $.get('@Url.Action("States", "Location")', { country: $(this).val() }, function (json) { 

This part is simple. I know how to do this, and I know that I can put this code in partial and display a partial view where I want the code to be displayed. This is not what I want to ask.

The code contained in the page layout is not cached, this is one thing. Another thing is that sometimes I need the same bit of code for multiple views, and I would like to save it in one place for maintenance. One place may be partial, but I want this code to be cached, ideally it would fall into a .js file. However, we cannot use server-side code in .js files. Keywords are cachable and single file .

I also know that I can have a dispatcher that will serve JavaScript, for example:

 <script src="@Url.Action("Script", "JS", { script = "location" }) type="text/javascript"></script> 

This controller action may return JavaScript as a result of rendering the view.

Or maybe I should stop being paranoid and just use regular .js files and put the identifiers and URLs of the elements there, and if I ever update my models or views, I would go and update the .js files. I am wondering if this is due to a development problem with .NET. I would be interested to know how people do it in Rails or django.

What I'm really looking for is "best practice" strategies. What do you do most often? How do you solve this problem?

+6
javascript asp.net-mvc
source share
2 answers

Caution: I do not do much with ASP.Net. But the problem is not ASP.Net, it is the same for all applications that have both server and client code.

I would probably have the ID ID of the main JavaScript file, and it will be retrieved from the variable, and your code for each page / page will generate variables for it. For example:

 <script type='text/javascript'> if (!window.Stuff) { window.Stuff = {}; } window.Stuff.MODEL_FIELD_SELECTOR = '#@Html.FieldIdFor(model => model.Name)'; </script> <script type='text/javascript' src='commonstuff.js'></script> 

In your commonstuff.js :

 $(Stuff.MODEL_FIELD_SELECTOR).autocomplete({... // (Or `window.Stuff.MODEL_FIELD_SELECTOR`, but unless you redefine `Stuff` // locally, there no need to prefix it.) 

Please note that I use only one global Stuff character to contain this stuff, so you will not pollute the global namespace more than necessary.

The idea here is to put the code in a cacheable, central, reusable place; but also just use dynamically generated code to set up the identifiers you need to work with.


Refresh . If you have several (or even many) of them, and I expect that you probably want to, and you use a character that you know you define, you can use object notation to make things more compact:

 <script type='text/javascript'> window.Stuff = { MODEL_FIELD_SELECTOR: '#@Html.FieldIdFor(model => model.Name)', SOME_OTHER_SELECTOR: '#@SomeOtherThing', SOMETHING_ELSE: '#@SomethingElse', // ... LAST_ONE: '#@TheLastOne' // ^ // Important: No trailing comma here | }; </script> <script type='text/javascript' src='commonstuff.js'></script> 

Note that the point is about the latter; IE7 and earlier choke in trailing commas at the ends of object literals ( more ).

+4
source share

One thing you can do is to get away from server side templates / views and go to client templates / views. Thus, all your controllers will only serve json, and you will bind this json as viewData to the templates directly in the browser. Templates can be cached as you serve them as a json object (for example). This is not a trivial implementation, but as soon as you start it and run both scaling and performance, like nothing you saw before.

+1
source share

All Articles