Reputation: 6813
I've got an MVC3 application in which I have javascript functions that have to call MVC Actions to either get data or redirect the page.
Currently the javascript is sitting in the cshtml file (using razor) so I can take advantage of Url.Action(..)
and Url.Content(..)
functions.
If I wanted to separate these files up, I'd lose the server side compilation of the files as the .js is not obviously handled by the razor engine.
Is it possible to create a cshtml view and return the content (Reponse.ContentType) as 'application/javascript' or is there another way I can achieved the desired result?
Thanks in advance
Sam
Upvotes: 1
Views: 1583
Reputation: 93424
A little known feature of script blocks is that you can provide a src attribute AND code in the block. So, you can do something like this:
<script type="text/javascript" src="@Url.Content("~/Scripts/Myscript.js")">
var myurl = `@Url.Action("SomeAction", "SomeController")`;
</script>
Then, in your script you can reference myurl.
Upvotes: 2
Reputation: 1038710
or is there another way I can achieved the desired result?
There is actually. Design your javascript functions so that they take those urls as parameters. Then all you have to do is to leave the initialization call in your view and pass the required urls:
<script type="text/javascript">
myJsInitialize('@Url.Action("Foo")', '@Url.Content("~/bar")');
</script>
or another possibility is to have those urls as part of the DOM that your javascript is working with. For example let's suppose that you have a link and you wish to send an AJAX request when this link is clicked:
@Html.ActionLink("click me", "someaction", null, new { id = "mylink" })
and in your separate js file you would use the href attribute of the link which already contains the url:
$('#mylink').click(function() {
$('#result').load(this.href);
return false;
});
But what if you needed for example another url in this function. Let's suppose for example that you needed to call an action using AJAX when the selction of a dropdown changes. In this case you could use HTML5 data-*
attributes on the dropdown:
@Html.DropDownListFor(
x => x.SelectedItem,
Model.Items,
new {
id = "myddl",
data_url = Url.Action("someaction")
}
)
and then in your separate javascript file:
$('#myddl').change(function() {
var selectedValue = $(this).val();
var url = $(this).data('url');
$.post(url, { value: selectedValue }, function(result) {
// ...
});
});
See how we no longer need to have the javascript functions depend on server side helpers such as Url.Action
or Url.Content
? This allows you to put them in separate javascript files without worrying that your application will stop working when you deploy it in a IIS virtual directory for example.
Upvotes: 4