rotem
rotem

Reputation: 103

Call an action from JS file instead of the view (MVC 4)

I'm using the MVC 4.

In my view i can simply get an action's url by using the: @Url.Action

Now i wanted to make a javascript file with all the view's javascript instead of writing it all in the view, the problem is i can't use the razor's stuff anymore.

so my question is how can i get the action's url from a javascript separated file?

Upvotes: 2

Views: 5307

Answers (4)

Ali Adravi
Ali Adravi

Reputation: 22723

If you want the root path, use a variable on layout and use that in JavaScript file, say

// In layout view
<script>
  var rootPath = @Url.Content("~/")
</script>

User rootPath anywhere in your application JavaScript files

If you want to get full path of a controller with action then

// View
<script>
  var url = @Url.Content("ActionName", "ControllerName")
</script>

use url in your JavaScript file.

Upvotes: 0

tanathos
tanathos

Reputation: 5606

Uhm... I think you can define a special route, like "actionsjs", that points to an action.

routes.MapRoute(name: "actionsJs",
                url: "actionsjs",
                defaults: new { controller = "Home", action = "GetActions" });

In the action you've to set the content to the right type:

Response.ContentType = "text/javascript";

Then you'll return a specific View that will contains javascript code with some Razor inside.

@{
    Layout = "";
}

$(function() {
    var a = @(1 + 2);
});

At this point you'll able to add this "script file" to your site:

<script type="text/javascript" scr="@Url.Action("GetActions", "Home")"></script>

Should work.

Upvotes: 0

Richard Neil Ilagan
Richard Neil Ilagan

Reputation: 14747

One way I did this before was to create views that served JS files (and CSS files, actually), instead of HTML files. This leverages the fact that views aren't necessarily HTML files all the time in the MVC paradigm.

You could do this by creating a controller for it:

public class AssetController : Controller {

    protected void SetMIME(string mimeType) {

        // implementation largely removed
        this.Response.Headers["Content-Type"] = mimeType;
        this.Response.ContentType = mimeType;
    }

    // this will render a view as a Javascript file
    public void ActionResult MyJavascript() {

        this.SetMIME("text/javascript");
        return View();
    }

}

Once you've done that, you can create a view (using the way you normally do it in ASP.NET MVC), and just write it up as Javascript. Remember not to use a layout, as you obviously don't want that.

Everything that views in MVC has to offer is available to you, so feel free to use models, et al.

@model IList<Entity>
@{
    Layout = null;
}

(function ($) {

    // javascript!

    @foreach(var entity in Model) {
        $('#@entity.Id').on('click', function () {
            console.log('@entity.Name');
        });
    }

})(jQuery);

Then you can wire that up using old-fashioned Razor in your other views.

<script src="@Url.Action("MyJavascript","Asset")"></script>

Which will roll out something like

<script src="http://your.domain/asset/myjavascript"></script>

Works like a charm. The views are dynamically created, of course, so be wary if you're nit-picky about that. However, since they are MVC controller actions and views, you can set cache options on them just as with any other view.

Upvotes: 0

dove
dove

Reputation: 20674

You'll need to define a JavaScript variable within your view that you can then use in your script. Obviously this must be declared first.

I use a helper on my layout pages that has all these variables and a section for any I'd want specific to a page. Note these would come before any other script references before the body tag.

@Scripts.Variables()
@RenderSection("ScriptVariables", false)

The Scripts.Variables is something like this

@helper Variables()
{
    <script language="javascript" type="text/javascript">
        var ActionGetallAdmin = '@Url.Action("GetAll", "Admin")';
        var ActionAccountLogin = '@Url.Action("Login", "Account")';
    </script>
}

Upvotes: 2

Related Questions