@Html.ActionLink and Angularjs value?
Asked Answered
A

4

14

Hey i'm currently workin on a project that has implemented angularjs, i was wondering if there is a way around to use angular value in Html Helper?

This is what I can't get to work:

@Html.ActionLink("Edit", "Edit", new { id = {{row.Id}} })

How do you use the value in razor syntax?

Armistead answered 7/8, 2014 at 12:40 Comment(0)
J
19

The problem with using ActionLink is that this method calls UrlPathEncode when creating URL. What this means is that razor directive {{}} with get encoded. Angular will not be able to evaluate it. What you will have to do is create this URL separately and then decode it. For example I have something like in one of the pages for our project.

@{
var url = Url.Action("Index", "Home", new{id="{{id=lastLatency}}"});
url = HttpUtility.UrlDecode(url);
}

<a data-ng-href="@url">Home</a>

It is very important that you use ng-href attribute to set the URL.

Junkie answered 7/8, 2014 at 16:42 Comment(5)
Thank you alot! Now I'm one step closer. The URL is updating with the parameter, but it doesn't trigger the site.Armistead
This really helped me. My requirement was a bit different I need to route to a specific page. So I used var url = Url.Action("Index","OtherPlace"); <a ng-href="@(url)#/routePage/{{vm.param1}}">someText</a>Outsert
@Junkie Is there a way to apply this to a button element?Hurlow
This does not work with route attributes. So if I put an attribute and define it as int.. then supplying a string does not bring back any url. It is a bit annoying that somebody decided to use route attributes... but yea. Just if somebody else runs into this problemVivie
I have written a quick extension based on all the answers here. I like your idea but I do not like mixing code on views. So following the Url.Helper I created an extension that works on strings from the routes. It is basic but it works great and follows the Razor style.Vivie
A
11

I found simple solution!

<a data-ng-href="@Url.Action("Edit", "Home")/{{row.Id}}" target="_self">Edit  </a>

But thanks for the respone, it got me a down the road to success!

Armistead answered 8/8, 2014 at 8:8 Comment(2)
The issue with this is that if "Edit" is your default action on the route it will create a shortened Url as in "Home/{{rowId}}".Ecker
-1 - Razor does not find the correct route because you need to supply a route value during the helper. So all I get is /9 - where is 9 is the ID I am trying to pass in. Instead of /home/edit/9Vivie
I
2

You can use ng-href and Url.Content as following

<a ng-href="@Url.Content("~/Home/Edit/"){{row.Id}}">Edit</a>
Imperforate answered 21/4, 2016 at 9:46 Comment(0)
V
0

Some of these answers provided here may have worked in 2014 but with newer releases of MVC, as of 2017 the routes do not work as expected or you may be be using [RoutingAttrbiutes] which allow you to easily adjust route names and parameters.

Based on all these answers here, ShaqCode and ByteBlocks I built a UrlHelper extension that help us make our lives a little bit easier now.

If you include this in the global namespace you do not need to import anything and you can just use it as follows'

<a ng-href="@Url.AngularActionLink("create", "purchaseorder", "supplierId", "{{supplier.Id}}")">Create</a>

And the extension class is as follows

public static class AngularUrlHelper
{
    public static List<string> RawRouteUrl;

    public static string AngularActionLink(this UrlHelper html, string actionName, string controller, string routeValue, string angularBinder)
    {
        var actionUrl = string.Empty;

        if (RawRouteUrl == null)
            RawRouteUrl = new List<string>();

        var routeQuery = $"{actionName}/{{{routeValue}}}";

        var rawRoute = RawRouteUrl.FirstOrDefault(x => x.Contains(routeQuery));

        if (string.IsNullOrWhiteSpace(rawRoute))
        {
        RawRouteUrl.Clear();

            foreach (var r in RouteTable.Routes)
            {
                try
                {
                    RawRouteUrl.Add(((Route)r).Url);
                }
                catch (System.Exception) { }
            }

            rawRoute = RawRouteUrl.FirstOrDefault(x => x.Contains(routeQuery));
        }

        if (!string.IsNullOrWhiteSpace(rawRoute))
        {
            actionUrl = rawRoute.Replace($"{{{routeValue}}}", angularBinder);
        }

        return actionUrl;
    }
}

And the result HTML will be angular ready.

<a ng-href="/create/purchaseorder/{{supplier.Id}}">Create</a>

Some more info.

I used a static list to make a really simple caching system per Application Pool. URL's will not really change unless you publish but they can change if you edit the .chstml file directly on the server.

So to accommodate a cache refresh, if the expected url query is not found it will attempt to rebuild the route string list.

The reason I did this cache thing is to avoid iterating constantly over the RouteTable.Routes - I tried to find a way to easily just get the string URL values from the RouteCollection - But for some reason it is practically impossible!? So hence.. this extension.

Vivie answered 9/3, 2017 at 12:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.