I want to validate certain condition before the browser follow the link dynamically created by ui-router.
I was looking into $rootscope.$on('$stateChangeStart', ..) but I have no access to the controller.$scope from there. I also need to use this in several places in the application and would be cumbersome.
Keep in mind that ui-sref is linked to ui-sref-active (work together), so i can't remove ui-sref and, by say, to use $state.$go('some-state') inside a function called with ng-click.
The condition should be evaluated inside a $scope function and on on-click event (before-transition with the ability to cancel it)
I need something like this:
<li ui-sref-active="active"> <a ui-sref="somestate" ui-sref-if="model.validate()">Go Somestate</a> </li> I tried:
<li ui-sref-active="active"> <a ui-sref="somestate" ng-click="$event.preventDefault()">Go Somestate</a> </li> <li ui-sref-active="active"> <a ui-sref="somestate" ng-click="$event.stopImmediatePropagation()">Go Somestate</a> </li> And
<li ui-sref-active="active"> <a ui-sref="somestate"> <span ng-click="$event.stopPropagation();">Go Somestate</span> </a> </li> Even
<li ui-sref-active="active"> <a ui-sref="somestate" onclick="return false;">Go Somestate</a> </li> But does not work.
SANDBOX
A ui-sref is a directive, and behaves similar to an html href . Instead of referencing a url like an href , it references a state. The ui-sref directive automatically builds a href attribute for you ( <a href=...> </a> ) based on your state's url.
ui-sref-active can live on the same element as ui-sref / ui-state , or it can be on a parent element. If a ui-sref-active is a parent to more than one ui-sref / ui-state , it will apply the CSS class when any of the links are active.
This answer inspired me to create a directive that allows me to interrupt the chain of events that end up changing state. For convenience and other uses also prevents the execution of ng-click on the same element.
javascript
module.directive('eatClickIf', ['$parse', '$rootScope', function($parse, $rootScope) { return { // this ensure eatClickIf be compiled before ngClick priority: 100, restrict: 'A', compile: function($element, attr) { var fn = $parse(attr.eatClickIf); return { pre: function link(scope, element) { var eventName = 'click'; element.on(eventName, function(event) { var callback = function() { if (fn(scope, {$event: event})) { // prevents ng-click to be executed event.stopImmediatePropagation(); // prevents href event.preventDefault(); return false; } }; if ($rootScope.$$phase) { scope.$evalAsync(callback); } else { scope.$apply(callback); } }); }, post: function() {} } } } } ]); html
<li ui-sref-active="active"> <a ui-sref="somestate" eat-click-if="!model.isValid()">Go Somestate</a> </li> PLUNKER
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With