Skip to content

Instantly share code, notes, and snippets.

@jnewman12
Last active February 16, 2017 04:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jnewman12/17095f46f10fd92a903bd7bec1e7ff3c to your computer and use it in GitHub Desktop.
Save jnewman12/17095f46f10fd92a903bd7bec1e7ff3c to your computer and use it in GitHub Desktop.
Routing Lecture

Front-end Routing with UI-Router

angular routing


Objectives

  • Understand the value of client side routing
  • Build a SPA with multiple pages
  • Describe when to consider server-side routing and when to consider front-end routing

High Level Routing

  • Routing, as you've seen in multiple frameworks and languages, is adding in the ability to render different pages in a application – but in a single-page app, how can we have multiple pages?
  • In Angular, it comes down to storing all our views on our main page and turning them on and off as we need.
  • But what's the benefit? Why even make it single page? Why add that complexity?
  • The main use case for front-end frameworks is added speed – by loading everything upfront, and just switching sections on and off, our page will seem wonderfully speedy because we'll be skipping quite a few steps that a more traditional framework has to run through.

What are the downsides?

  • There are downsides though -- if we really store an entire complex app on a single page, it becomes huge and unweildy.
  • Also, what about URL's? They're the primary tool of navigation on the web, and they're how our users share links to certain parts of our application.
  • SEO: although SEO is out of the scope of this course, SEO is hugely important as I'm sure you have found out about the existance of websites based solely on their SEO rankings
  • Compatability. Based on which browsers you're targeting, your preferred method of client-side routing might not be supported.
  • The biggest things to remember is that even thouugh all of the above are downsides, these problems have all been solved. They might just involve some more work

How it works under the hood

  • While all this might seem complex, and it is, it's simply broken down into a couple steps:
    1. The browser detects that the user has clicked on an anchor element, just like before (i.e. server rendered pages).
    2. A client side code (usually the routing library) catches this event, detects that the URL is not an external link, and then prevents the browser from making the HTTP GET request.
    3. The routing library then manually changes the URL displayed in the browser (using the HTML5 history API, or maybe URL hashbangs on older browsers)
    4. The routing library then changes the state of the client app. For example, it can change the root React/Angular/etc component according to the route rules.
    5. The app (particularly the MVC library, like React) then processes state changes. It renders the new components, and if necessary, it requests new data from the server.

client side routing


Routing Options

  • angular has 2 main ways to route inside your app
    • NgRoute and Ui Router
  • We are gonna focus on Ui Router because it is a slightly better alternative. But you are welcome to explore NgRoute

WHAT IS ANGULARUI ROUTER?

The UI-Router is a routing framework for AngularJS built by the AngularUI team. It provides a different approach than ngRoute in that it changes your application views based on state of the application and not just the route URL.

STATES VS URL ROUTE

With this approach, your views and routes aren’t tied down to the site URL (like ngRoute). This way, you can change the parts of your site using your routing even if the URL does not change.

When using ngRoute, you’d have to use ngInclude or other methods and this could get confusing. Now that all of your states, routing, and views are handled in your one .config(), this would help when using a top-down view of your application.


Our sample app

  • We are going to be building an app to display some (or most) of the features Ui-Router gives us
  • Start by grabbing the sample code, and let's get to coding
  • Note: like some of the other complex things we have done (rails walk throughs, SQL walkthroughs, express walkthroughs etc) we are going to be using code already on here so you can come back here as a resource later if you need it.

index.html

  • Let's look at our HTML file.
  • We will use Bootstrap to help with our styling. Notice that we also load up ui-router in addition to loading Angular.
  • This is because UI Router is separate from the Angular core, just like ngRoute is separate.

ui-sref????

  • When creating a link with UI-Router, you will use ui-sref. The href will be generated from this and you want this to point to a certain state of your application. These are created in your app.js.
  • We also use <div ui-view></div> instead of ngRoute’s <div ng-view></div>.

app.js

  • Now let's open up our app.js.
  • One of the first things to notice, is we are writing in a different syntax. Instead of naming functions to fill in as arguments, we are inlining functions. This wasnt added for confusion...only to show how you can write your apps in multiple ways.
  • This looks pretty bare...let's add our first 2 routes
.state('home', {
  url: '/home',
  templateUrl: 'partial-home.html'
})
  • this is our home state, or our main state, and is what our app defaults to
  • inside it, we are telling angular whenever we are on this state, it is to render a certain template. In this case partial-home.html
  • Notice $urlRouterProvider.otherwise('/home');. What this is saying is any time angular can't find a view (or errors out), it will redirect back to this state
  • let's add another blank state that we will circle back to and fill in later
.state('about', {
    // we'll get to this in a bit       
});
  • the last part, is let's add our html file to our home view.
  • inside partial-home.html, let's add this
<div class="jumbotron text-center">
  <h1>The Homey Page</h1>
  <p>This page demonstrates <span class="text-danger">nested</span> views.</p>
</div>
Viewing
  • now before we view these files, we need to set up our servers. You guys all have a server on your machine which might be different from mine. So load up your servers how you do and open your app in there.
  • assuming everything works, we should all see something like this

home state


Nested Views

  • Let’s look at how we can nest views.
  • We’ll add two buttons to our home page and from there, we will want to show off different information based on what is clicked.
  • We’re going to add our buttons to partial-home.html and then go into our Angular file and see how we can change it to add nested views.
  • Let's add the following to partial-home.html
<div class="jumbotron text-center">
  <h1>The Homey Page</h1>
  <p>This page demonstrates <span class="text-danger">nested</span> views.</p>  

  <a ui-sref=".list" class="btn btn-primary">List</a>
  <a ui-sref=".paragraph" class="btn btn-danger">Paragraph</a>
</div>

<div ui-view></div>
  • notice the additional ui-view like the one on our home page. This is where the nested nature comes in.
  • When linking to a nested view, we are going to use dot denotation: ui-sref=".list" and ui-sref=".paragraph".
  • These will be defined in our Angular file and once we set it up there, we will inject into our new <div ui-view></div>.
  • Now, in our app.js file, let’s create those nested states.
.state('home', {
    url: '/home',
    templateUrl: 'partial-home.html'
})

// nested list with custom controller
.state('home.list', {
    url: '/list',
    templateUrl: 'partial-home-list.html',
    controller: function($scope) {
        $scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
    }
})

// nested list with just some random string data
.state('home.paragraph', {
    url: '/paragraph',
    template: 'Learning angular is awesome'
})
  • Now the ui-sref we defined in home.html are linked to an actual state. With home.list and home.paragraph created, those links will now take the template provided and inject it into ui-view.
  • Last thing we need to do for the home page is define the partial-home-list.html file. We have also passed in a controller with a list of dogs that we will use in the template file.
    • this is important syntax. Here we are inlining a controller. But we could just as easily defined a controller and passed it in as a string DogsController, and added a seperate file for it. But for this example, we can just inline a controller for use in this particular view
  • Now, inside partial-home-list.html let's add this
<ul>
    <li ng-repeat="dog in dogs">{{ dog }}</li>
</ul>
  • Now when we click List, it will inject our list of dogs into the template.
  • Or if we click Paragraph, it will inject the string we gave.

Multiple Views in the About Page

  • wait what? Multiple views?
  • yes, with some cool tricks, we can render multiple views inside one view
  • Having multiple views in your application can be very powerful. Maybe you have a sidebar on your site that has things like Popular Posts, Recent Posts, or anything else. These can all be separated out and injected into our template.
  • Each will have its own controller and template file so our app stays clean.
  • Having our application modular like this also lets us reuse data in different templates.
  • For our About page, let’s make two columns and have each have its own data.
  • We will handle the view first and then look at how we can do this using UI-Router.
  • lets add the following to our partial-about.html file
<div class="jumbotron text-center">
    <h1>The About Page</h1>
    <p>This page demonstrates <span class="text-danger">multiple</span> and <span class="text-danger">named</span> views.</p>
</div>

<div class="row">

    <!-- COLUMN ONE NAMED VIEW -->
    <div class="col-sm-6">
        <div ui-view="columnOne"></div>
    </div>
    
    <!-- COLUMN TWO NAMED VIEW -->
    <div class="col-sm-6">
        <div ui-view="columnTwo"></div>
    </div>

</div>    
  • There we have multiple views. One is named columnOne and the other is columnTwo.

  • Why would we use this approach? That’s a good question. Are we creating an application that is too modularized and that could get confusing?

  • Here is a solid example (taken from the angular docs) of why you would have multiple named views.

  • In their example, they show off different parts of an application. Each part has its own data, so having each with its own controllers and template files makes building something like this easy.

  • Now that our view is all created, let’s look at how we can apply template files and controllers to each view. We’ll go back to our `app.js.

  • Warning: This syntax might look weird, but we are going to show it because some of you may need to use this in your projects

  • paste this inside where our about state is

// app.js
.state('about', {
  url: '/about',
  views: {
    // the main template will be placed here (relatively named)
    '': { templateUrl: 'partial-about.html' },

    // the child views will be defined here (absolutely named)
    'columnOne@about': { template: 'Look I am a column!' },

    // for column two, we'll define a separate controller
    'columnTwo@about': {
      templateUrl: 'table-data.html',
      controller: 'techController'
    }
  }
});
  • then, right below it, let's add our techController
routerApp.controller('techController', function($scope) {
  $scope.message = 'test';

  $scope.techList = [
    {
      name: 'Rails',
      status: 'Legendary'
    },
    {
      name: 'React',
      status: 'New Kid'
    },
    {
      name: 'Angular',
      status: 'Tricks for HTML'
    }
  ];
});
  • notice more new syntax! We are inlining our controller instead of manually adding it as a function like this
routerApp.controller('techController', techController)
techController.$inject = ['$scope']

function techController($scope) {
  $scope.message = 'test';

  $scope.techList = [
    {
      name: 'Rails',
      status: 'Legendary'
    },
    {
      name: 'React',
      status: 'New Kid'
    },
    {
      name: 'Angular',
      status: 'New Tricks for HTML'
    }
  ];
}
  • the final piece of this is to add our table-data.html
  • let's open that file and add this
<h2>Some Tech</h2>
<table class="table table-striped table-bordered">
	<tr>
		<th>Name</th>
		<th>Status</th>
	</tr>
	<tr ng-repeat="tech in techList">
		<td>{{tech.name}}</td>
		<td>{{tech.status}}</td>
	</tr>
</table>

Conclusion

  • What's a router? What's it for?
  • How do we add routes to our Angular application?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment