Calling angularjs scope function from href
Solution 1
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.
Solution 2
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);
}
}
});
Solution 3
You should probably use ng-click here.
Solution 4
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
Solution 5
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.
user1200387
Updated on July 30, 2022Comments
-
user1200387 almost 2 years
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.
-
user1200387 over 10 yearsThe most beautiful hack I have seen. Works like a charm!
-
user1200387 over 10 yearsI 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.
-
user1200387 over 10 yearsOk figured out I have to be on the $$childHead object first like so... angular.element("directive-name").scope().$$childHead and it works!
-
Dvid Silva almost 10 yearsthis should be the top answer :/
-
thetallweeks over 9 yearsYou could you also use
scope.$eval
instead of$parse
to avoid the need for dependency injection. See modified jsfiddle. -
th1rdey3 over 8 yearsthis code will not work if minified. see modified jsfiddle which will work with minification.
-
Alberto La Rocca over 8 yearsThe 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, theclick
event is not semantic. -
Alberto La Rocca over 8 yearsSee my comment above,
ng-click
handles theclick
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.