You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
974 lines
29 KiB
974 lines
29 KiB
# AngularJS - Routing
|
|
|
|
|
|
## Lesson Outline
|
|
|
|
We will be creating a basic page about a Vet. This will have links which load various template files via the Angular Router. Final code is available in the `instructor_examples/routing` directory, but I'll be building it temporarily in `instructor_examples/live_coding`.
|
|
|
|
1. Running Angular Server with http-server
|
|
1. Routing Overview
|
|
1. Mini exercise
|
|
1. What we are building
|
|
1. Push State Overview
|
|
1. Write initial HTML
|
|
1. Write initial JavaScript and app config
|
|
1. Enable HTML5 Push state
|
|
1. Create Contact Template
|
|
1. Create Contact Controller
|
|
1. Create Contact Route
|
|
1. Create About Template and Route
|
|
1. Pets page; Using parameter from URL, Route / Controller / Template
|
|
1. Pricing page; Pass data from Route to Template
|
|
1. Joke page; using template script tag
|
|
1. All page; nesting partials/templates
|
|
1. Default / Fallback Page
|
|
1. Google Link / External page
|
|
1. Final Code
|
|
|
|
|
|
## Running Angular Server with http-server
|
|
|
|
**Note:** Sometimes the page gets cached and updates are not seen. Try a hard refresh by holding down the shift key when you refresh
|
|
|
|
Sometimes hard refresh isn't enough, try `clear browsing history`
|
|
|
|
We're going to create a basic AngularJS application, without an Express server for this exercise. We want to be able to browser to [http://localhost:8080](http://localhost:8080). We are *not* using `nodemon` for this exercise, nor do we need `mongod`.
|
|
|
|
- Install `npm-server` by running `npm install -g http-server` from the terminal.
|
|
- Create a directory called `routing`. `mkdir routing` and `cd routing`
|
|
- Create empty `app.js` and `index.html` files inside of it. `touch app.js index.html`
|
|
- Run the server with `http-server -o`
|
|
- View the (currently blank) files by browsing to [http://localhost:8080](http://localhost:8080)
|
|
|
|
## Routing Overview
|
|
|
|
The Angular Router enables navigation from one view and controllers to the next as users perform application tasks such as clicking on links.
|
|
|
|
This is similar the routing in Express that we saw prior, and the routing that we will see in Rails in Unit 4.
|
|
|
|
Another way to think about it is when you have a specific URL, you want to have a specific section of code run.
|
|
|
|
For example, you might have `/products` to show an index of all your products, `/products/:id` to show a single product, `/login` that displays the login screen, ` /register` that displays the registration screen.
|
|
|
|
Routing will also pass the application *parameters* from the URL, such as a product id, or a search query string like `/search?query=apple`. The application can then use these parameters as a form of user input.
|
|
|
|
### Mini Exercise
|
|
|
|
Write a short list of three possible routes that an application might have, and one parameter that you might use for input. Respond in a thread here on Slack.
|
|
|
|
## What We Are Building
|
|
|
|
We're going to build the beginnings an AngularJS application, focusing almost exclusively on the routes. The view templates, controllers, HTML and CSS will be bare-bones to let us focus on this.
|
|
|
|
My cat Jade is feeling a little sick, so we're going to think about building a basic page for a Veterinarian.
|
|
|
|

|
|
|
|
Pages we need:
|
|
|
|
- Home (/)
|
|
- Contact (`/contact`)
|
|
- About (`/about`)
|
|
- Pricing (`/pricing`)
|
|
- Cats (`/pets/cats`) - Both of these will use just one route/controller/template
|
|
- Dogs (`/pets/dogs`) - Both of these will use just one route/controller/template
|
|
- Joke of the Day (`/joke`) - This will use an inline template
|
|
- All (`/all`) - This will combine multiple templates
|
|
- Bad URL (`/badurl`) - This will show a default / fallback page
|
|
- Link to Google - external link
|
|
|
|
These are a bit arbitrary and artificial of goals, but will help give us some more context to talk about specific links.
|
|
|
|
## Push State Overview
|
|
|
|
You can update the browser's url without refreshing the page using JS
|
|
|
|
- this is called Push State. It's part of HTML5
|
|
- up until recently, the only way to update the url is make a new requests
|
|
- click a link
|
|
- type into browser's url bar and hit enter
|
|
- now you can do that with javascript
|
|
|
|
What can Angular do with this?
|
|
|
|
- angular will listen for changes in the url
|
|
- next, angular will render a template into a specific part of the page that we define
|
|
- it will then attach a controller to this template and alias it `as` a variable which can be referenced in the HTML
|
|
|
|
### Write Initial HTML
|
|
|
|
We're going to setup most of the HTML we need upfront. This is a bit much to type, but this is the biggest single section of code we'll see at once here.
|
|
|
|
- We need to include Angular and [ngRoute](https://docs.angularjs.org/api/ngRoute), which is a separate file
|
|
- This approach is similar to express, where functionality that is not crucial is moved to separate packages (ejs, method-override, etc...)
|
|
- Add a link the `/contact` and other pages outlined above. You do this as you'd create any other relative link. In a moment, we'll see how to handle this with our JavaScript.
|
|
- Add a reference to our JavaScript file in the html, and add `<body ng-app="VetApp">`
|
|
- Next, tell angular where to render the templates with the `ng-view` directive
|
|
- Route relative to a base url (/ in this case) with `<base href="/">`
|
|
|
|
|
|
file: `index.html`
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title></title>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js" charset="utf-8"></script>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.min.js" charset="utf-8"></script>
|
|
<script src="app.js" charset="utf-8"></script>
|
|
<base href="/" target="_blank">
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<h1>Vets and Pets!</h1>
|
|
<nav>
|
|
<ul>
|
|
<li><a href="/">Home (/)</a></li>
|
|
<li><a href="/contact">Contact</a></li>
|
|
<li><a href="/about">About</a></li>
|
|
<li><a href="/pricing">Pricing</a></li>
|
|
<li><a href="/joke">Joke of the Day</a></li>
|
|
</ul>
|
|
|
|
<h3>Pets</h3>
|
|
<ul>
|
|
<li><a href="/pets/cats">Cats</a></li>
|
|
<li><a href="/pets/dogs">Dogs</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- This is the main view that will be filled in with view templates -->
|
|
<main ng-view></main>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
## Write initial JS
|
|
|
|
We need one dependency for our module
|
|
|
|
file: `app.js`
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
```
|
|
|
|
We need to create a `config` for our module to make this work. A module config runs only once at load time.
|
|
|
|
file: js/app.js
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
//.config just runs once on load. Looks like a controller, but without a name
|
|
app.config(function() { });
|
|
```
|
|
|
|
Let's add two important services. This is via Dependency Injection, and will perhaps seem a little odd at first.
|
|
|
|
- `$locationProvider` handles push state
|
|
- push state
|
|
- allows you to update the URL in your browser without reloading the page
|
|
- also updates your history when URL changes via push state
|
|
- `$routeProvider`
|
|
- creates event listeners which render a template into ng-view when the browser URL matches its URL
|
|
|
|
file: `app.js`
|
|
```javascript
|
|
//include $routeProvider and $locationProvider
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
|
|
// Enables Push State
|
|
$locationProvider.html5Mode({ enabled: true });
|
|
}]);
|
|
```
|
|
|
|
## Create Contact Templates
|
|
|
|
Create a partial file that has some text inside of it, and uses the `ctrl.phone`, which we will populate and link together with the Controller and Route in the next steps
|
|
|
|
file: contact.html
|
|
```html
|
|
<h2>Contact Us:</h2>
|
|
{{ctrl.phone}}
|
|
```
|
|
|
|
## Create Contact Controller
|
|
|
|
file: `app.js`
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
app.controller('ContactController', function () {
|
|
this.phone = '555-1212';
|
|
});
|
|
|
|
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
|
|
// Enables Push State
|
|
$locationProvider.html5Mode({ enabled: true });
|
|
}]);
|
|
```
|
|
|
|
## Create Contact Route
|
|
|
|
Now let's add a basic route within the config function. We'll use the `ContactController` we added above to tie to all together. After this, the link should show a new view when clicked on!
|
|
|
|
```javascript
|
|
$routeProvider.when('/contact', {
|
|
templateUrl: 'contact.html', // render http://localhost:3000/contact.html
|
|
controller: 'ContactController', // attach controller ContactController
|
|
controllerAs: 'ctrl' // alias for ContactController (like ng-controller="ContactController as ctrl")
|
|
});
|
|
```
|
|
|
|
*Question for Slack*: Why would a controller alias be useful? Respond in a threaded message.
|
|
|
|
Then we create a basic empty controller by adding `app.controller('ContactController', function() { });`. Then assign the value of `this.phone` so we can use it in the template.
|
|
|
|
file: `app.js`
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
app.controller('ContactController', function () {
|
|
this.phone = '555-1212';
|
|
});
|
|
|
|
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
|
|
// Enables Push State
|
|
$locationProvider.html5Mode({ enabled: true });
|
|
|
|
$routeProvider.when('/contact', {
|
|
templateUrl: 'contact.html',
|
|
controller: 'ContactController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
}]);
|
|
```
|
|
|
|
## You Turn:
|
|
|
|
Make a template, route and controller for a `/about` page. Don't worry about passing data from the controller to the template.
|
|
|
|
## Using URL Params for Individual Pets Pages
|
|
|
|
We can access url params with a pattern that is similar to express:
|
|
|
|
```javascript
|
|
$routeProvider.when('/pets/:id', { // when http://localhost:3000/pets/:id - :id is a param just like in express
|
|
templateUrl: 'pets.html',
|
|
controller: 'PetController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
```
|
|
Inside the controller, we can access those url params using `$routeParams` that we pass to the function:
|
|
|
|
```javascript
|
|
app.controller('PetController', ['$routeParams', function ($routeParams) {
|
|
this.id = $routeParams.id; //access :id from url
|
|
}]);
|
|
```
|
|
|
|
These are used to pass `cats` and `dogs` from the links we created earlier in the `ul` elements, but they could be used to pass numbers or other data from the URL into the routes and controller:
|
|
|
|
```html
|
|
<h3>Pets</h3>
|
|
<ul>
|
|
<li><a href="/pets/cats">Cats</a></li>
|
|
<li><a href="/pets/dogs">Dogs</a></li>
|
|
</ul>
|
|
```
|
|
|
|
file: `app.js`
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
app.controller('ContactController', function () {
|
|
this.phone = '555-1212';
|
|
});
|
|
|
|
app.controller('PetController', ['$routeParams', function ($routeParams) {
|
|
// access :id from url
|
|
this.id = $routeParams.id;
|
|
}]);
|
|
|
|
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
|
|
// Enables Push State
|
|
$locationProvider.html5Mode({ enabled: true });
|
|
|
|
$routeProvider.when('/contact', {
|
|
templateUrl: 'contact.html',
|
|
controller: 'ContactController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/about', {
|
|
templateUrl: 'about.html'
|
|
// We don't need to specify a controller, because there's no data
|
|
});
|
|
|
|
// when http://localhost:3000/url1/:id - :id is a param just like in express
|
|
$routeProvider.when('/pets/:id', {
|
|
templateUrl: 'pets.html',
|
|
controller: 'PetController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
}]);
|
|
```
|
|
|
|
## Create Pricing Page: Pass data from Route to Controller to Template
|
|
|
|
You can pass data from the route into the controller, and then use it in a template.
|
|
|
|
Here we pass the price of *$1 million dollars* from the route to the controller. Note the function definition uses `$route` instead of `$routeParams`!
|
|
|
|
Create a `PricingController`, route and template:
|
|
|
|
file: `app.js`
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
app.controller('ContactController', function () {
|
|
this.phone = '555-1212';
|
|
});
|
|
|
|
app.controller('PetController', ['$routeParams', function ($routeParams) {
|
|
// access :id from url
|
|
this.id = $routeParams.id;
|
|
}]);
|
|
|
|
app.controller('PricingController', ['$route', function ($route) {
|
|
this.price = $route.current.price;
|
|
}]);
|
|
|
|
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
|
|
// Enables Push State
|
|
$locationProvider.html5Mode({ enabled: true });
|
|
|
|
$routeProvider.when('/contact', {
|
|
templateUrl: 'contact.html',
|
|
controller: 'ContactController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/about', {
|
|
templateUrl: 'about.html'
|
|
// We don't need to specify a controller, because there's no data
|
|
});
|
|
|
|
// when http://localhost:3000/url1/:id - :id is a param just like in express
|
|
$routeProvider.when('/pets/:id', {
|
|
templateUrl: 'pets.html',
|
|
controller: 'PetController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/pricing', {
|
|
templateUrl: 'pricing.html',
|
|
controller: 'PricingController',
|
|
controllerAs: 'ctrl',
|
|
price: '$1 trillion dollars'
|
|
});
|
|
}]);
|
|
```
|
|
|
|
file: `pricing.html`
|
|
```html
|
|
<h2>Pricing</h2>
|
|
{{ctrl.price}}
|
|
```
|
|
|
|
|
|
file: `app.js`
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
app.controller('ContactController', function () {
|
|
this.phone = '555-1212';
|
|
});
|
|
|
|
app.controller('PetController', ['$routeParams', function ($routeParams) {
|
|
// access :id from url
|
|
this.id = $routeParams.id;
|
|
}]);
|
|
|
|
app.controller('PricingController', ['$route', function ($route) {
|
|
this.price = $route.current.price;
|
|
}]);
|
|
|
|
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
|
|
// Enables Push State
|
|
$locationProvider.html5Mode({ enabled: true });
|
|
|
|
$routeProvider.when('/contact', {
|
|
templateUrl: 'contact.html',
|
|
controller: 'ContactController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/about', {
|
|
templateUrl: 'about.html'
|
|
// We don't need to specify a controller, because there's no data
|
|
});
|
|
|
|
// when http://localhost:3000/url1/:id - :id is a param just like in express
|
|
$routeProvider.when('/pets/:id', {
|
|
templateUrl: 'pets.html',
|
|
controller: 'PetController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/pricing', {
|
|
templateUrl: 'pricing.html',
|
|
controller: 'PricingController',
|
|
controllerAs: 'ctrl',
|
|
price: '$1 trillion dollars'
|
|
});
|
|
}]);
|
|
```
|
|
|
|
|
|
## Joke page; using template script tag
|
|
|
|
You can have a template inside a script tag instead of an external file.
|
|
|
|
- the advantage to this is that it doesn't need to make an extra http request to get the template
|
|
- the downside is that your html gets more bloated
|
|
|
|
Here we'll create a `joke.html` template, but instead of making a new file, we'll put the contents inside a `script` tag in `index.html`. Also, create a link to `/joke` in the navigation list.
|
|
|
|
```html
|
|
<script type="text/ng-template" id='joke.html'>
|
|
<h2>Pet Joke of the Day<h2/>
|
|
<p>{{ctrl.joke}}</p>
|
|
</script>
|
|
```
|
|
|
|
file: `index.html`
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title></title>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js" charset="utf-8"></script>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.min.js" charset="utf-8"></script>
|
|
<script src="app.js" charset="utf-8"></script>
|
|
<base href="/" target="_blank">
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<h1>Vets and Pets!</h1>
|
|
<nav>
|
|
<ul>
|
|
<li><a href="/">Home (/)</a></li>
|
|
<li><a href="/contact">Contact</a></li>
|
|
<li><a href="/about">About</a></li>
|
|
<li><a href="/pricing">Pricing</a></li>
|
|
<li><a href="/joke">Joke of the Day</a></li>
|
|
</ul>
|
|
|
|
<h3>Pets</h3>
|
|
<ul>
|
|
<li><a href="/pets/cats">Cats</a></li>
|
|
<li><a href="/pets/dogs">Dogs</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- This is the main view that will be filled in with view templates -->
|
|
<main ng-view></main>
|
|
|
|
<script type="text/ng-template" id='joke.html'>
|
|
<h2>Pet Joke of the Day</h2>
|
|
<p>{{ctrl.joke}}</p>
|
|
</script>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
Then, create a `JokeController` and `/joke` route. Also, create an array of jokes in the `JokeController`, and pass the first one to `this.joke` so that the joke is displayed in the template.
|
|
|
|
If you have a moment of extra time, try to figure out how to make a random joke appear each time on the page.
|
|
|
|
|
|
file `app.js`
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
app.controller('ContactController', function () {
|
|
this.phone = '555-1212';
|
|
});
|
|
|
|
app.controller('PetController', ['$routeParams', function ($routeParams) {
|
|
// access :id from url
|
|
this.id = $routeParams.id;
|
|
}]);
|
|
|
|
app.controller('JokeController', ['$route', function () {
|
|
this.joke = "Why don't cats like online shopping? They prefere a cat-alogue"
|
|
}]);
|
|
|
|
app.controller('PricingController', ['$route', function ($route) {
|
|
this.price = $route.current.price;
|
|
}]);
|
|
|
|
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
|
|
// Enables Push State
|
|
$locationProvider.html5Mode({ enabled: true });
|
|
|
|
$routeProvider.when('/contact', {
|
|
templateUrl: 'contact.html',
|
|
controller: 'ContactController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/about', {
|
|
templateUrl: 'about.html'
|
|
// We don't need to specify a controller, because there's no data
|
|
});
|
|
|
|
// when http://localhost:3000/url1/:id - :id is a param just like in express
|
|
$routeProvider.when('/pets/:id', {
|
|
templateUrl: 'pets.html',
|
|
controller: 'PetController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/pricing', {
|
|
templateUrl: 'pricing.html',
|
|
controller: 'PricingController',
|
|
controllerAs: 'ctrl',
|
|
price: '$1 trillion dollars'
|
|
});
|
|
|
|
$routeProvider.when('/joke', {
|
|
templateUrl: 'joke.html',
|
|
controller: 'JokeController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
}]);
|
|
```
|
|
|
|
## All Page - Nesting Partials/Templates
|
|
|
|
Combining multiple partials is possible by having multiple `ng-include` elements in an html file. This is a great way to reuse code. Our example here is a bit artificial, but will show you how to reuse partials we've already created above all together.
|
|
|
|
Create an `all.html` file, and make `ng-include` elements for `contact.html`, `pricing.html` and `joke.html`.
|
|
|
|
file: `all.html`
|
|
```html
|
|
<ng-include src="contact.html"></ng-include>
|
|
<ng-include src="pricing.html"></ng-include>
|
|
<ng-include src="joke.html"></ng-include>
|
|
```
|
|
|
|
Then create a link to `/all` in the `index.html`
|
|
|
|
file: `index.html`
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title></title>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js" charset="utf-8"></script>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.min.js" charset="utf-8"></script>
|
|
<script src="app.js" charset="utf-8"></script>
|
|
<base href="/" target="_blank">
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<h1>Vets and Pets!</h1>
|
|
<nav>
|
|
<ul>
|
|
<li><a href="/">Home (/)</a></li>
|
|
<li><a href="/contact">Contact</a></li>
|
|
<li><a href="/about">About</a></li>
|
|
<li><a href="/pricing">Pricing</a></li>
|
|
<li><a href="/joke">Joke of the Day</a></li>
|
|
<li><a href="/all">Contact, Pricing and Joke!</a></li>
|
|
</ul>
|
|
|
|
<h3>Pets</h3>
|
|
<ul>
|
|
<li><a href="/pets/cats">Cats</a></li>
|
|
<li><a href="/pets/dogs">Dogs</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- This is the main view that will be filled in with view templates -->
|
|
<main ng-view></main>
|
|
|
|
<script type="text/ng-template" id='joke.html'>
|
|
<h2>Pet Joke of the Day</h2>
|
|
<p>{{ctrl.joke}}</p>
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
Create an `AllController` that will give us the data needed for those partials. There are cleaner ways of not-repeating ourselves for this data, but for now let's just repeat the code to keep things simple.
|
|
|
|
Then, create a route to `/all` that will use the `AllController` and the `all.html` partial.
|
|
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
app.controller('ContactController', function () {
|
|
this.phone = '555-1212';
|
|
});
|
|
|
|
app.controller('PetController', ['$routeParams', function ($routeParams) {
|
|
// access :id from url
|
|
this.id = $routeParams.id;
|
|
}]);
|
|
|
|
app.controller('JokeController', ['$route', function () {
|
|
const jokes = ["Why don't cats like dogs?",
|
|
"What is the difference between a duck?"];
|
|
|
|
//you can access variables created in the when action like this
|
|
this.joke = jokes[0];
|
|
}]);
|
|
|
|
app.controller('PricingController', ['$route', function ($route) {
|
|
this.price = $route.current.price;
|
|
}]);
|
|
|
|
app.controller('AllController', ['$route', function () {
|
|
const jokes = ["Why don't cats like dogs?",
|
|
"What is the difference between a duck?"];
|
|
|
|
this.joke = jokes[1];
|
|
this.phone = '555-1212';
|
|
this.price = '$1 billion dollars';
|
|
}]);
|
|
|
|
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
|
|
// Enables Push State
|
|
$locationProvider.html5Mode({ enabled: true });
|
|
|
|
$routeProvider.when('/contact', {
|
|
templateUrl: 'contact.html',
|
|
controller: 'ContactController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/about', {
|
|
templateUrl: 'about.html'
|
|
// We don't need to specify a controller, because there's no data
|
|
});
|
|
|
|
// when http://localhost:3000/url1/:id - :id is a param just like in express
|
|
$routeProvider.when('/pets/:id', {
|
|
templateUrl: 'pets.html',
|
|
controller: 'PetController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/pricing', {
|
|
templateUrl: 'pricing.html',
|
|
controller: 'PricingController',
|
|
controllerAs: 'ctrl',
|
|
price: '$1 trillion dollars'
|
|
});
|
|
|
|
$routeProvider.when('/joke', {
|
|
templateUrl: 'joke.html',
|
|
controller: 'JokeController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/all', {
|
|
templateUrl: 'all.html',
|
|
controller: 'AllController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
}]);
|
|
```
|
|
|
|
## Default / Fallback routes
|
|
|
|
What if we have a link that doesn't match the routes defined? We can set a catch-all default route in that case using `otherwise`. You can either have a specific controller and template you'd like to use, or you can redirect it with `redirectTo` in the `app.js` file.
|
|
|
|
```javascript
|
|
$routeProvider.otherwise({
|
|
redirectTo: '/'
|
|
});
|
|
```
|
|
|
|
In `index.html` then you can put a link do a page that otherwise doesn't exist:
|
|
|
|
```html
|
|
<a href="/badurl">/badurl</a>
|
|
```
|
|
|
|
Afterward, `app.js` and `index.html` should look like these:
|
|
|
|
file: `app.js`
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
app.controller('ContactController', function () {
|
|
this.phone = '555-1212';
|
|
});
|
|
|
|
app.controller('PetController', ['$routeParams', function ($routeParams) {
|
|
// access :id from url
|
|
this.id = $routeParams.id;
|
|
}]);
|
|
|
|
app.controller('JokeController', ['$route', function () {
|
|
const jokes = ["Why don't cats like dogs?",
|
|
"What is the difference between a duck?"];
|
|
|
|
//you can access variables created in the when action like this
|
|
this.joke = jokes[0];
|
|
}]);
|
|
|
|
app.controller('PricingController', ['$route', function ($route) {
|
|
this.price = $route.current.price;
|
|
}]);
|
|
|
|
app.controller('AllController', ['$route', function () {
|
|
const jokes = ["Why don't cats like dogs?",
|
|
"What is the difference between a duck?"];
|
|
|
|
this.joke = jokes[1];
|
|
this.phone = '555-1212';
|
|
this.price = '$1 billion dollars';
|
|
}]);
|
|
|
|
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
|
|
// Enables Push State
|
|
$locationProvider.html5Mode({ enabled: true });
|
|
|
|
$routeProvider.when('/contact', {
|
|
templateUrl: 'contact.html',
|
|
controller: 'ContactController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/about', {
|
|
templateUrl: 'about.html'
|
|
// We don't need to specify a controller, because there's no data
|
|
});
|
|
|
|
// when http://localhost:3000/url1/:id - :id is a param just like in express
|
|
$routeProvider.when('/pets/:id', {
|
|
templateUrl: 'pets.html',
|
|
controller: 'PetController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/pricing', {
|
|
templateUrl: 'pricing.html',
|
|
controller: 'PricingController',
|
|
controllerAs: 'ctrl',
|
|
price: '$1 trillion dollars'
|
|
});
|
|
|
|
$routeProvider.when('/joke', {
|
|
templateUrl: 'joke.html',
|
|
controller: 'JokeController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/all', {
|
|
templateUrl: 'all.html',
|
|
controller: 'AllController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.otherwise({
|
|
redirectTo: '/'
|
|
});
|
|
}]);
|
|
```
|
|
|
|
file: `index.html`
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title></title>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js" charset="utf-8"></script>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.min.js" charset="utf-8"></script>
|
|
<script src="app.js" charset="utf-8"></script>
|
|
<base href="/" target="_blank">
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<h1>Vets and Pets!</h1>
|
|
<nav>
|
|
<ul>
|
|
<li><a href="/">Home (/)</a></li>
|
|
<li><a href="/contact">Contact</a></li>
|
|
<li><a href="/about">About</a></li>
|
|
<li><a href="/pricing">Pricing</a></li>
|
|
<li><a href="/joke">Joke of the Day</a></li>
|
|
<li><a href="/all">Contact, Pricing and Joke!</a></li>
|
|
<li><a href="/badurl">/badurl</a>, redirects to default home page (/)</li>
|
|
</ul>
|
|
|
|
<h3>Pets</h3>
|
|
<ul>
|
|
<li><a href="/pets/cats">Cats</a></li>
|
|
<li><a href="/pets/dogs">Dogs</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- This is the main view that will be filled in with view templates -->
|
|
<main ng-view></main>
|
|
|
|
<script type="text/ng-template" id='joke.html'>
|
|
<h2>Pet Joke of the Day</h2>
|
|
<p>{{ctrl.joke}}</p>
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
## Google Link / External Pages
|
|
|
|
If we include a link to another site using `http`, instead of `https` it skips the AngularJS Routes and simply opens a new tab/window.
|
|
|
|
We do this by just adding a standard link in the `index.html`
|
|
```html
|
|
<li><a href="http://www.google.com">google</a></li>
|
|
```
|
|
|
|
## Final code
|
|
|
|
Here are our main two files, `index.html` and `app.js`. The partial files can be found in `instructor_examples/routing`
|
|
|
|
file: `index.html`
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title></title>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js" charset="utf-8"></script>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.min.js" charset="utf-8"></script>
|
|
<script src="app.js" charset="utf-8"></script>
|
|
<base href="/" target="_blank">
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<h1>Vets and Pets!</h1>
|
|
<nav>
|
|
<ul>
|
|
<li><a href="/">Home (/)</a></li>
|
|
<li><a href="/contact">Contact</a></li>
|
|
<li><a href="/about">About</a></li>
|
|
<li><a href="/pricing">Pricing</a></li>
|
|
<li><a href="/joke">Joke of the Day</a></li>
|
|
<li><a href="/all">Contact, Pricing and Joke!</a></li>
|
|
<li><a href="/badurl">/badurl</a>, redirects to default home page (/)</li>
|
|
|
|
<!-- only this link skips the router because it starts with http -->
|
|
<li><a href="http://www.google.com">google</a> loads external site</li>
|
|
</ul>
|
|
|
|
<h3>Pets</h3>
|
|
<ul>
|
|
<li><a href="/pets/cats">Cats</a></li>
|
|
<li><a href="/pets/dogs">Dogs</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- This is the main view that will be filled in with view templates -->
|
|
<main ng-view></main>
|
|
|
|
<script type="text/ng-template" id='joke.html'>
|
|
<h2>Pet Joke of the Day</h2>
|
|
<p>{{ctrl.joke}}</p>
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
file: `app.js`
|
|
```javascript
|
|
const app = angular.module('MyApp', ['ngRoute']);
|
|
|
|
app.controller('ContactController', function () {
|
|
this.phone = '555-1212';
|
|
});
|
|
|
|
app.controller('PetController', ['$routeParams', function ($routeParams) {
|
|
// access :id from url
|
|
this.id = $routeParams.id;
|
|
}]);
|
|
|
|
app.controller('JokeController', ['$route', function () {
|
|
const jokes = ["Why don't cats like dogs?",
|
|
"What is the difference between a duck?"];
|
|
|
|
//you can access variables created in the when action like this
|
|
this.joke = jokes[0];
|
|
}]);
|
|
|
|
app.controller('PricingController', ['$route', function ($route) {
|
|
this.price = $route.current.price;
|
|
}]);
|
|
|
|
app.controller('AllController', ['$route', function () {
|
|
const jokes = ["Why don't cats like dogs?",
|
|
"What is the difference between a duck?"];
|
|
|
|
this.joke = jokes[1];
|
|
this.phone = '555-1212';
|
|
this.price = '$1 billion dollars';
|
|
}]);
|
|
|
|
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
|
|
// Enables Push State
|
|
$locationProvider.html5Mode({ enabled: true });
|
|
|
|
$routeProvider.when('/contact', {
|
|
templateUrl: 'contact.html',
|
|
controller: 'ContactController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/about', {
|
|
templateUrl: 'about.html'
|
|
// We don't need to specify a controller, because there's no data
|
|
});
|
|
|
|
// when http://localhost:3000/url1/:id - :id is a param just like in express
|
|
$routeProvider.when('/pets/:id', {
|
|
templateUrl: 'pets.html',
|
|
controller: 'PetController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/pricing', {
|
|
templateUrl: 'pricing.html',
|
|
controller: 'PricingController',
|
|
controllerAs: 'ctrl',
|
|
price: '$1 trillion dollars'
|
|
});
|
|
|
|
$routeProvider.when('/joke', {
|
|
templateUrl: 'joke.html',
|
|
controller: 'JokeController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.when('/all', {
|
|
templateUrl: 'all.html',
|
|
controller: 'AllController',
|
|
controllerAs: 'ctrl'
|
|
});
|
|
|
|
$routeProvider.otherwise({
|
|
// if browser url doesn't match any of the above...
|
|
// here you can do something like above if you'd like with a template and a controller
|
|
redirectTo: '/' // or you can redirect to another url.
|
|
// redirection can happen in any 'when' action; I just happened to do it here.
|
|
// I could have put it in one of the above sections too
|
|
});
|
|
}]);
|
|
```
|