Introduction to ui-router

AngularJS - Introduction to ui-router AngularJS Video Tutorial by Joel Hooks

In his debut egghead.io lesson, Joel will show you how to get setup and running with ui-router, an alternative to AngularJS's default routing module.


Bower issues with ui-router v0.2.8

You need to use this in bower.json to get the proper current version of ui-router: "angular-ui-router": "0.2.8-bowratic-tedium",. There was an issue with the original v0.2.8 release and bower.

The ability to reply to discussions is limited to PRO subscribers. Want to join in the discussion? Click here to subscribe now.

egghead.io comment guidelines

egghead.io
Avatar

In his debut egghead.io lesson, Joel will show you how to get setup and running with ui-router, an alternative to AngularJS's default routing module.


index.html

<!DOCTYPE html>
<html ng-app="uiRouterExample">
<head>
  <link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.min.css" />
  <link rel="stylesheet" href="css/app.css" />
</head>
<body>

  <div class="container">
    <h4>
        A brief introduction to <strong class="text-danger">ui-router</strong>
        <span class="text-muted">(v0.2.0)</span>
    </h4>
    <div>
        <ul class="nav nav-pills">
            <li><a href="#/home">Home</a></li>
            <li><a href="#/list">Shopping List</a></li>
        </ul>
    </div>
    <div ui-view></div>
  </div>

  <script type="text/javascript" src="vendor/underscore/underscore.js"></script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js"></script>
  <script type="text/javascript" src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
  <script type="text/javascript" src="app/app.js"></script>
</body>
</html>

home.html

<div class="row">
    <h3>What is ui-router?</h3>

    <p>URL routing is a popular approach to matching the contents of a URL to specific functionality within a web
        application. URL routes programmatically present specific content to users based on the URL that they are
        visiting. It is a popular approach that has proven to be very effective.</p>

    <P>Something that might not be obvious is that URL routing is also a finite state machine. When you configure
        the routing for an app, you are laying out the various states the application can be in, and informing the
        application what to display and do when a specific route is encountered.</P>

    <p>AngularJS supplies URL routing by default. It is adequate, but also has some limitations.</p>
</div>

list.html

<div class="row padded">
    <div class="list-group col-xs-3">
        <a class="list-group-item"
            ng-repeat="item in shoppingList"
            ng-class="{active: item.selected}"
            ng-href="#/list/{{item.name}}"
            ng-click="selectItem(item)">{{item.name}}</a>
    </div>
    <div ui-view class="col-xs-9"></div>
</div>

list.item.html

<img ng-src="/assets/images/{{item}}.jpg" class="img-responsive" />

app.js

angular.module("uiRouterExample", ["ui.router"])

.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider
    .state('home', {
        url: '/home',
        templateUrl: 'templates/home.html'
    })
    .state('list', {
        url: '/list',
        templateUrl: 'templates/list.html',
        controller: 'ListCtrl'
    })
    .state('list.item', {
        url: '/:item',
        templateUrl: 'templates/list.item.html',
        controller: function($scope, $stateParams) {
            $scope.item = $stateParams.item;
        }
    })
})

.controller("ListCtrl", function($scope) {
    $scope.shoppingList = [
      {name: 'Milk'},
      {name: 'Eggs'},
      {name: 'Bread'},
      {name: 'Cheese'},
      {name: 'Ham'}
    ];

    $scope.selectItem = function(selectedItem) {
        _($scope.shoppingList).each(function(item) {
            item.selected = false;
            if (selectedItem === item) {
                selectedItem.selected = true;
            }
        });
    };
})

Joel Hooks: ui-router is an alternative routing mechanism for your angularJS applications. It has some advantages over the default router and angularJS, primarily around the ability to have nested views. Once you've imported ui-router into your application the first thing you need to do is actually bring the module in as a dependency for your application.

After that, we need to configure ui-router and you'll notice that we have a $stateProvider within our config function as well as a URL router provider. We'll use the $stateProvider to define our first state. The first state within our application is going to be the home state. The home state has a URL of home and it also has a template URL that is pointed at a partial that we've created called home.html.

We'll refresh our application and home doesn't actually take us anywhere yet. We need to do a couple of things. First thing we need to do is actually define our ui view. ui-view is ui-router's version of ng-view. This is how it knows where to inject your views within your application. Once we define that ui-view, our home URL actually displays our content as expected.

We're going to define another state. We need to define a list state and its URL is going to be \list and it's also going to have a templateURL, and templates with .HTML. With our second state defined, we go to our shopping list, and it's blank. This is because we haven't connected it to our controller. I've predefined a controller and we're going to connect it now.

You can do this within your state configuration. You can also use ng-controller to do this as you might do in other applications. Once we've defined our controller, and we refresh our list, you will notice that I have a shopping list here of some simple items that we need to pick up from the store.

You are able to select these items. If you're paying attention, you'll notice in the corner that as I select these items it's actually going to an alternative URL. It's going to list\milk-eggs-bread-cheese. What we want to do is display an image for each of the items that are in our list. I'm going to do that by defining another state. I'm going to call that state list.item.

Ui-router understands this dot notation and knows that item is actually a child of the list view. I'll give that a URL of :item. This is a parameterized URL. I don't need to, or want to define the full URL.

Ui-writer understands that this is a child and will append this parameterized URL to the list state's URL. The full URL will be /list/:item and we'll have our parameterized URL. Point it at its template, save that, refresh, and we don't actually get our image that we expect.

We'll come over here and take a look at this, and we'll notice quickly that it's looking for an item object on the scope. It's [inaudible 03:12] down to that, but we don't actually have a particular scope and there is no item on that scope for this view.

To solve that, we're going to define another controller. It's actually going to be a function. We're going to pass in our scope and we're going to pass in $stateParams. This is an injection that ui-router provides and it will actually provide the parameter that's passed within our URL. On our scope, we want an item, and it's going to equal to $stateParams.item

I will refresh, select, we're still not getting anything. If I come over here to our list, we've defined a DIV that should hold our image. However, we need to put ui-view on here. Now ui-router understands that this is the nested view that corresponds to our list item.

When I refresh, I get pictures for milk, for eggs, for bread, for cheese. I can come back to shopping list. It'll maintain that state between these. It understands the selected one, it's not actually redrawing the shopping lists each time I change the state and replace this view entirely on the right.

Tech logo bar

Don't miss out on the latest PRO lessons.

Get Your PRO Subscription Now

Because you like code... not PowerPoint slides.