10

I am using a library which appends a href element onto an tag. On this link I need to make a call to an angularjs function that is within scope. Something like...

<a href="{{someFunction()}}"></a>

Note: I am attaching this href via javascript from another library (nvd3.js) not actually writing this in because if I was I could easily use ng-click or ng-href.

7 Answers 7

19

So I was not pleased with the answer to this as it doesn't really utilize an elegant angular solution.

Here's my solution: http://jsfiddle.net/jjosef/XwZ93

HTML:

<body class="wrapper" ng-app="ExampleApp">
  <a my-href="buildUrl('one', aVariable, 'three')">This is my a tag with a function that builds the url</a>
</body>

JS:

angular.module('ExampleApp', []);
angular.module('ExampleApp').run(function($rootScope) {
  $rootScope.buildUrl = function() {
    var link = [];
    for(var i = 0; i < arguments.length; i++) {
      link.push(arguments[i].toLowerCase());
    }
    return '/#!/' + link.join('/');
  };

  $rootScope.aVariable = 'two';
});

angular.module('ExampleApp').directive('myHref', function($parse) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      var url = $parse(attrs.myHref)(scope);
      element.attr('href', url);
    }
  }
});
Sign up to request clarification or add additional context in comments.

3 Comments

this should be the top answer :/
You could you also use scope.$eval instead of $parse to avoid the need for dependency injection. See modified jsfiddle.
this code will not work if minified. see modified jsfiddle which will work with minification.
14

That's a bit convoluted.

CAVEAT: This is very, very hacky and just absolutely exactly what you're NOT supposed to do in angular, but I guess you know that and the library is making your life hard...

First, unlike onclick, an href won't interpret a string as javascript. Instead, you'd have to use

<a href="javascript:someFunction()"></a>

But this alone won't make it work, because someFunction() is not a method on the document, but on the controller, so we need to get the controller first:

<a href="javascript:angular.element(
         document.getElementById('myController')).scope().someFunction();"></a>

Where myController refers to the DOM element that is decorated with ng-controller, e.g.

<div data-ng-controller="SomeController" id="myController"> ... </div>

If someFunction modifies the state of the view, you'll also need to use $scope.apply, i.e.

<a href="javascript:angular.element(document.getElementById('myController')).
           scope().$apply(someFunction)"></a>

Note that you don't need the {{ }} syntax, because you're calling javascript directly, you're not asking angular to modify your markup.

3 Comments

The most beautiful hack I have seen. Works like a charm!
I thought it was working but jumped the gun: This is definitely the right track. Here is what I tried:angular.element('directive-name').scope().loadUsers(1); And the error said angular.element(...).scope(...).loadUsers is not a function. When I type angular.element('directive-name') it returns the proper object with the scope() function on it.
Ok figured out I have to be on the $$childHead object first like so... angular.element("directive-name").scope().$$childHead and it works!
9

You should probably use ng-click here.

1 Comment

The problem with ng-click is it would only detect clicks and not when the user navigates to the element with the Tab key and then press Space. In other words, the click event is not semantic.
2

The simplest solution is

<a href="" ng-click="someFunction(x,y,z)">Go</a>

href="" is important, otherwise hover cursor style does not change to a pointer

1 Comment

See my comment above, ng-click handles the click DOM event, which is not semantic: it detects clicks but it doesn't detect when the user navigates to the element with the Tab key and then presses Space.
1

I mixed some things here and I have it working.

I have a menu with some options, each one calls a different method on the controller.

<span ng-show="hoverOptions" ng-mouseleave="hoverOut()" class="qk-select ui-select-container qk-select--div">
    <ul>
        <li ng-repeat="option in menuOptions"><a href="javascript:void(0);" ng-click="callFunction(option.action)">{{option.name}}</a></li>
    </ul>
</span>

The callFunction method in the controller is defined like that:

$scope.callFunction = function (name){
      if(angular.isFunction($scope[name]))
                $scope[name]();
}

And the menu options are defined also in the controller in that way:

$scope.menuOptions = [{action: "uploadPhoto" , name:"Cargar foto"}, {action: "logout", name:"Cerrar sesión"}, {action: "createUser", name:"Nuevo usuario"}];

Hope it helps someone.

Comments

0

You'll need to use $parse() to process the tag when using {{someFn}}.

Comments

0

solution: https://embed.plnkr.co/bhMcEO/

<!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8" />
      <title>$window or $location to Redirect URL in AngularJS</title>
      <link rel="stylesheet" href="style.css" />
      <script src="https://code.angularjs.org/1.4.1/angular.js"></script>
      <script>
        var app = angular.module('RedirectURLApp', []);
        app.controller('RedirectURLCtrl', function($scope, $window) {
          $scope.name = 'Anil';
          $scope.RedirectToURL = function() {
            var host = $window.location.host;
            var landingUrl = "http://www.google.com";
            alert(landingUrl);
            $window.location.href = landingUrl;
          };
        });
      </script>
    </head>
    <body ng-app="RedirectURLApp">
      <div ng-controller="RedirectURLCtrl">
        <h2>$window or $location to Redirect URL in AngularJS</h2>
        <p>Hello {{name}},</p>
        Click to Redirect <a href="" ng-click="RedirectToURL()">Click Me!</a>
      </div>
      <div><h4><a href="http://www.code-sample.com/2015/06/redirect-to-new-page-using-location-or.html">For more detail..</a></h4></div>
    </body>
    </html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.