views:

831

answers:

4

I've been working with ASP.NET MVC and Javascript/jQuery a lot lately and I seem to be heading in a direction where I'm always needing to pass some dynamic value "to" my javascript. When the script is right in the page, I've done something like this:

var isEditable = <%=ViewData["editable"]%>

I like how this is quick & easy and just like I'd inject a value into HTML. But this smells. Really, really bad. And it breaks Visual Studio's intellisense and code formatting, making my scripts hard to read and understand.

It has occurred to me another solution would be to pass my data to a hidden field, and have the Javascript reference that...

<input type="hidden" id="editable" value="<%=ViewData["editable"]%>" />
var isEditable = $("#editable").attr("value");

This is probably much better as it keeps the script intact and would allow me to move it to an external .js file. But something about this solution doesn't seem ideal either. Or is it just me?

Can anyone recommend solutions & best practices for passing data into your scripts? Am I headed down the wrong path if my scripts end up heavily relying the viewdata from my controllers in the first place?

+1  A: 

You are going to inject that information one way or another. And IMO, your first example aren't really different from the second one.

Another solution is to have a JS class (or prototype?) that will accept an options object. Though admittedly, it's not really different than the examples you've given. But still, maybe you'd want to go this way.

$(function () {
    myClass.init({ isEditable: <%=ViewData["editable"]%>, 
        another: '<%=ViewData["another"]%>' });
});
çağdaş
+5  A: 

I sometimes pass data to my pages by writing a config object to the page via a JSON serializer:

var pageConfig = <%= ServerConfig.ToJson() %>;

Where you need to write the ToJson method yourself. This keeps the page state nicely contained, so that there is only one place where you inject server values. Everything from here on out is pure javascript. In your example, you could then do:

var isEditable = pageConfig.isEditable;

even in an external js file, if pageConfig is global. In that case, though, you should properly namespace it: MY_APP.pageConfig perhaps.

Gabe Moothart
Doesn't this affect chacheability? At the very least each page GET may return a different page (different configuration). When thinking in terms of caches in proxy servers, now you'll have a different version of that page for each user. Is that a concern at all?
John Saunders
This is an intriguing option, but I'm not sure I understand exactly how you're implementing this ServerConfig class. Indeed each page GET may return a different set of data, so wouldn't pageConfig ultimately needd to be set from the ViewData of each page? Regardless, your other suggestions are something I'll definitely try/consider (Json and a global js variable) - thanks!
Kurt Schindler
@Kurt - yeah, I think you'd have to build it from the ViewData (maybe as an anonymous type). I didn't mean you could get rid of ViewData, but that you could limit the number of places you're injecting server data on the page.
Gabe Moothart
A: 

I think @çağdaş makes a good point, but remember to check server side too. If you set a field to "read only" there's nothing to prevent the user from modifying that flag, changing a read-only field, and submitting.

chris
A: 

The entire business of Ajax is to load information asynchronously. If you're doing Ajax's job (loading the info and keeping it in a variable), that's taking power away from it. Why don't you try JQuery and use it's Ajax, or Get functions to load the content dynamically. It would help your page load faster.

Cyril Gupta