0

I am transitioning my SPA from ng-route to ui.router. This should be a quick one for someone...

For some of my states, I have $rootScope.nextState and $rootscope.prevState attributes defined (statename strings), so that I can have Previous and Next buttons / links on my navbar.

I can't seem to get the link correct. I have tried:

<button ui-sref="{{prevState}}">Previous</button>

<button ui-sref={{prevState}}>Previous</button>

<button ui-sref="{prevState}">Previous</button>

<button ui-sref="prevState">Previous</button>

<button ng-href="{{$state.href(prevState)}}">Previous</button>

<button ng-click="$state.go(prevState)">Previous</button>

All of the above with <a> instead.

All throw an "Invalid state ref" error or don't change the state. How can you use a dynamic attribute for statename in ui-router?

I have read and understood the docs to the best of my ability. Similar questions that haven't helped: https://stackoverflow.com/questions/23476296/dynamically-constructed-ui-sref-attribute-in-ui-router and https://stackoverflow.com/questions/24349731/dynamically-set-the-value-of-ui-sref-angularjs

Here's a Plunker recreating the problem. It uses resolve in a method similar to angular-ui-router-title. It might be the timing of things that's the issue...

Community
  • 1
  • 1
StevieP
  • 401
  • 3
  • 16
  • Works fine here: http://plnkr.co/edit/X2ZWuKN46B6auQTo9KeE?p=preview. Post a plunkr reproducing the problem. – JB Nizet Nov 11 '15 at 16:10
  • Thanks, @JBNizet - show's it's possible (and teaches me correct syntax!) Plunker added. – StevieP Nov 11 '15 at 16:35
  • 1
    I've managed to get it almost working: http://plnkr.co/edit/xjNwmPPW6oEg7k7DtW4z?p=preview. $state was undefined. Everything fell down because ui-sref throws if trying to use an undefined state. And resolve fields are supposed to be functions returning something. Not strings. But it seems ui-sref doesn't watch the changes to the expression, so once the next button is displayed, it doesn't change its target location even if next changes in the scope. I think you should simply have an ng-click calling a function of the scope, that would programmatically call $state.go(). It makes things easier. – JB Nizet Nov 11 '15 at 16:56

1 Answers1

0

For future readers, I went with @JB Nizet's suggestion.

HTML

<button ng-click="goPrevious()" ng-disabled="!previousState">Previous</button>
<button ng-click="goNext()" ng-disabled="!nextState">Next</button>

JS

app.run( function($rootScope, $state) {

  $rootScope.$on('$stateChangeSuccess', function () {

    var previous = $state.$current.locals.globals.$prevState;
    var next = $state.$current.locals.globals.$nextState;

    $rootScope.previousState = previous;
    $rootScope.nextState = next;

    if (typeof previous !== 'undefined') {
        $rootScope.goPrevious = function() { $state.go(previous); };
    } else {
        $rootScope.goPrevious = function() { console.log ("No previous state found"); };
    }
    if (typeof next !== 'undefined') {
        $rootScope.goNext = function() { $state.go(next); };
    } else {
        $rootScope.goNext = function() { console.log ("No next state found"); };
    }

  });
});
StevieP
  • 401
  • 3
  • 16