Last Updated: February 25, 2016
·
2.39K
· creatordave

Simple, automatic toggle effect with Angular's ui-router

So I assume you know about Angular's ui-router and how it works. I've been using it for quite a while now and today I discovered a new trick that may or may not be obvious to some.

I tried looking for similar examples used by others. Even checked the documentation, but managed to find nothing to reference. So I decided to share this with you all, and perhaps let me know what you think.

Usually when I use ui-router, I tend to have something similar to this in my template:

<div ui-view></div>

Basically, an empty html element with ui-view attribute. Depending on the current state, a template will be rendered inside the above div.

However, let's say you have a state that shows a list, and at the bottom of the list, there's an add button to add something else to the list. When you click the add button, a form is displayed below the list, replacing the button.

Step 1

Picture

Step 2

Picture

Very simple. Once the form is submitted, the view goes back to its previous state.

At first, I was going to keep track of the current state by referencing it in the controller's $scope. The button would have an ng-show attribute and depending on the current state, show or hide accordingly. Basically, something like this:

<!-- list goes here -->
<button ng-show="currentState == 'list'">
    Add New Item
</button>
<div ui-view>
    <!-- 'list.add' form rendered here -->
</div>

This would definitely work, but you would have to keep track of the state and make sure to refresh it from the controller.

The same thing can be achieved by simply moving the button inside the container with the ui-view attribute.

<!-- list goes here -->

<div ui-view>
    <button ui-sref='.add'>
        Add New Item
    </button>
    <!-- 'list.add' form will be rendered here and replace anything inside this container, including the button -->
</div>

But that's not what I found surprising. What was surprising is the fact that once you tell the state to go a step back, the initial content set inside the ui-view, in this case, the add button, is rendered again:

$state.go('^');

The add button inside the ui-view will reappear, giving the user a sense of toggle effect.

This may have been obvious, but I never assumed that this was a feature in ui-router and I never stumbled on anything similar, anywhere. I always assumed that once anything new is rendered in the ui-view, it will be lost unless the state is re-rendered from scratch.

Also built a quick plunker for demonstration:
http://plnkr.co/edit/6BqKMY?p=preview