22

In my current project using asp.net MVC 3 (using razor), when I'm making Ajax calls, I have to keep the JS on the view page because I want to use Url.Action to generate the URL. This means I can't split the js code out into .JS files, Is there a better solution than what I'm currently doing.

tjdecke
  • 567
  • 4
  • 11
Simon
  • 415
  • 1
  • 4
  • 15
  • Simon, I recently answered this question but actually found the accepted answer to be a much neater solution. take a look here for a nice simple solution to your problem: http://stackoverflow.com/questions/4624626/do-you-write-your-javascript-in-a-asp-net-mvc-view-or-in-a-separate-javascrip/4625478#4625478 cheers.. – jim tollan Jan 24 '11 at 12:16

4 Answers4

17

I tend to accomplish this in a similar way as above, with a slightly different twist as I like namespacing my javascript.

The javascript file looks something like:

var my = {};

my.viewname = 
{
   init : function(settings){
      // do some work here. settings.someImportantUrl has my json/ajax url eg.
      alert(settings.someImportantUrl );
   }
}

Then my view would contain something like:

<script language='javascript'>
  // allocate an object with variables you want to use in the external js file
  var settings = {someImportantUrl: '<%=Url.Action(...)%>'};
  // call an init method for the current view
  my.viewname.init(settings);
</script>
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • So jamiec, to pull the URL's out of the JS again I just use JS object notation like var url = my.namespace.settings.UserEditUrl, is this correct? – Simon Jan 24 '11 at 13:25
  • @Simon - within the `init` method, you can use settings.whatever to access variables you have allocated within the view to the settings object. re-read example, it should be clear. – Jamiec Jan 24 '11 at 14:40
  • jamie, just to add, you would of course add `var my = {};` to your initial javascript file section :-) – jim tollan Jan 24 '11 at 16:18
  • think I'll go with your suggestion Jamie, one off topic question though, why namespace your JS, what does this bring to the table, Cheers – Simon Jan 24 '11 at 17:01
  • 2
    @Simon - The same thing namespaces bring to any programming; organisation, clarity & good practice. – Jamiec Jan 24 '11 at 17:19
9

You can define only urls in view and keep all other javascript code in .js files.

There is code from view in my MVC.NET 1 application:

<script type="text/javascript" src="<%=Url.Content("~/Scripts/Account/ManageUsers.js")%>"></script>

<script type="text/javascript" src="<%=Url.Content("~/Scripts/Account/ManageUsersAndGroups.js")%>"></script>

<script type="text/javascript">

    var getUsersUrl = '<%= Url.Action("GetUsers", "Account") %>';
    var getUserDetailsURL = '<%= Url.Action("GetUserDetails", "Account") %>';

    <%If Not ViewData("readOnly") Then%>
    var changeRolePermissionsUrl = '<%= Url.Action("ChangeRolePermissions", "Account") %>';
    var deleteUserUrl = '<%= Url.Action("DeleteUser", "Account") %>';
    var resetPasswordUrl = '<%= Url.Action("ResetPassword", "Account") %>';
    var updateUserGroupsUrl = '<%= Url.Action("UpdateUserGroups", "Account") %>';
    var updateUserDetailsUrl = '<%= Url.Action("UpdateUserDetails", "Account") %>';
    <%End If%>  
</script>

So, you can even don't render urls for actions which cannot be invoked by user because of security reasons. (ViewData("readOnly") means user have read only access to screen).

And there is a part of code in js file:

function GetUsersList() {
    ajax.getJSON(getUsersUrl, {}, function(data) {
        if (data != false) {
            ShowUsers(data);
        }
        else {
            jAlert('Error during users list retrieving.');
        }
    });
}

Where getUsersUrl is defined in View

Egor4eg
  • 2,678
  • 1
  • 22
  • 41
  • I was thinking along these lines, i.e. Keeping a collection of all my Ajax urls in a shared ascx and maintaining that, I just want to make sure I'm not missing something else that may have been easier – Simon Jan 24 '11 at 12:02
  • I'm not seeing a better way. But I could say that my practise is good. It is used in a big project for about 1.5 year and we don't have any problems in development and maintenance. – Egor4eg Jan 24 '11 at 12:37
  • This is the best solution i get. Thanks @Egor4eg – Rajan Mishra Feb 28 '17 at 12:51
1

I'm not sure of security ramifications on this, but another way to do it would be to use the @Url.Action to set the 'id' of the html markup, then you can create a javascript click function, like the following:

View

<div class="someClickable" id='@Url.Action("Action", "Controller")'>
</div>

Referenced javascript file

$(function() {
    $('someClickable').click(function () {
        $.ajax({
            url: this.id,
            success: someJSFunction,
            dataType: "html"
        });
    });
});

You end up with the desired url stored in the 'id' of the 'div'. This seems to be a reasonable solution as long as you are doing read only actions.

scott-pascoe
  • 1,463
  • 1
  • 13
  • 31
1

your javascript code should be reside in separate javascript file. you can use global variables to link your view and javascript. E.g. view page looks like below.

view html ...
<script type="text/javascript">
var pageUrl = @GetURL()
</script>

<script type="text/javascript" src="/js/script.js"/>

script.js file use the pageUrl variable and other global variables.

Adeel
  • 19,075
  • 4
  • 46
  • 60
  • but I'll still need to hard code the URL path inside the JS file, and I don't want to do this I want MVC to create the Url's for me. – Simon Jan 24 '11 at 11:59
  • @Simon no you don't need to hardcode path inside js due to global variables defined in your view, generated by MVC – Adeel Jan 24 '11 at 12:14
  • ah ok, Adeel, your suggestion is similar to Egor4eg answer below. – Simon Jan 24 '11 at 13:23