Книга: Angular 2 Cookbook
Назад: 6. The Component Router
Дальше: Navigating with routerLinks

Setting up an application to support simple routes

Central to the behavior of single-page applications is the ability to perform navigation without a formal browser page reload. Angular 2 is well-equipped to work around the default browser page reload behavior and allow you to define a routing structure within it, which will make it look and feel like actual page navigation.

Note

The code, links, and a live example of this are available at .

Getting ready

Suppose you have the following function defined globally:

function visit(uri) {     // For this recipe, you don't care about the state or title     window.history.pushState(null, null, uri);   }   

The purpose of this is to merely allow you to navigate inside the browser from JavaScript using the HTML5 History API.

How to do it...

In order for Angular to simulate page navigation inside the browser, there are several steps you must take to create a navigable single-page application.

Setting the base URL

The first step in configuring your application is to specify the base URL. This instructs the browser what network requests performed with a relative URL should begin with.

Anytime the page makes a request using a relative URL, when generating the network request, it will use the current domain and then append the relative URL. For relative URLs, a prepended "/" means it will always use the root directory. If the forward slash is unavailable, the relative path will prepend whatever is specified as the base href. Any URL behavior, including requesting static resources, anchor links, and the history API, will exhibit this behavior.

Note

<base> is not a part of Angular but rather a default HTML5 element.

Here are some examples of this:

 [Example 1]   // <base href="/">   // initial page location: foo.com      visit('bar');   // new page location: foo.com/bar      visit('bar');   // new page location: foo.com/bar   // The browser recognizes that this is a relative path   // with no prepended / and so it will visit the page at the   // same "depth" as before.      visit('bar/');   // new page location: foo.com/bar/   // Same as before, but the trailing slash will be important once   // you invoke this again.      visit('bar/');   // new page location: foo.com/bar/bar/   // The browser recognizes that the URL ends with a /, and so   // visiting a relative path is treated as a navigation into a    // subpath      visit('/qux');   // new page location: foo.com/qux   // With a / prepended to the URL, the browser recognizes that it   // should navigate from the root domain     [Example 2]   // <base href="xyz/">   // initial page location: foo.com      visit('bar');   // new page location: foo.com/xyz/bar   // Base URL is prepended to the relative URL      visit('bar');   // new page location: foo.com/xyz/bar   // As was the case before, the local path is treated the same   // by the browser      visit('/qux');   // new page location: foo.com/qux   // Note that in this case, you specified a relative path    // originating from the root domain, so the base href is ignored   

Defining routes

Next, you need to define what your application's routes are. For the purpose of this recipe, it is more important to understand the setup of routing than how to define and navigate between routes. So, for now, you will just define a single catchall route.

As you might suspect, route views in Angular 2 are defined as components. Each route path is represented at the very least by the string that the browser's location will match against and the component that it will map to. This can be done with an object implementing the Routes interface, which is an array of route definitions.

It makes sense that the route definitions should happen very early in the application initialization, so you'll do it inside the top-level module definition.

First, create your view component that this route will map to:

[app/default.component.ts]      import {Component} from '@angular/core';      @Component({     template: 'Default component!'   })   export class DefaultComponent {}    

Next, wherever your application module is defined, import RouterModule and the Routes interface, namely DefaultComponent, and define a catchall route inside the Routes array:

[app/app.module.ts]       import {NgModule} from '@angular/core';   import {BrowserModule} from '@angular/platform-browser';   import {RouterModule, Routes} from '@angular/router';   import {RootComponent} from './root.component';   import {DefaultComponent} from './default.component';      const appRoutes:Routes = [     {path: '**', component: DefaultComponent}   ];      @NgModule({     imports: [       BrowserModule     ],     declarations: [       DefaultComponent,       RootComponent     ],     bootstrap: [       RootComponent     ]   })   export class AppModule {}    

Providing routes to the application

You've defined the routes in an object, but your application still is not aware that they exist. You can do this with the forRoot method defined in RouterModule. This function does all the dirty work of installing your routes in the application as well as passing along a number of routing providers for use elsewhere in the application:

[app/app.module.ts]      import {NgModule} from '@angular/core';   import {BrowserModule} from '@angular/platform-browser';   import {RouterModule, Routes} from '@angular/router';   import {RootComponent} from './root.component';   import {DefaultComponent} from './default.component';      const appRoutes:Routes = [     {path: '**', component: DefaultComponent}   ];      @NgModule({     imports: [       BrowserModule,       RouterModule.forRoot(appRoutes)     ],     declarations: [       DefaultComponent,       RootComponent     ],     bootstrap: [       RootComponent     ]   })   export class AppModule {}    

With this, your application is fully configured to understand the route you have defined.

Rendering route components with RouterOutlet

The component needs a place to be rendered, and in Angular 2, this takes the form of a RouterOutlet tag. This directive will be targeted by the component attached to the active route, and the component will be rendered inside it. To keep things simple, in this recipe, you can use the directive inside the root application component:

[app/app.component.ts]      import {Component} from '@angular/core';      @Component({     selector: 'root',     template: `       <h1>Root component</h1>       <router-outlet></router-outlet>     `   })   export class RootComponent {}   

That's all! Your application now has a single route defined that will render DefaultComponent inside RootComponent.

How it works...

This recipe doesn't show a very complicated example of routing, since every possible route that you can visit will lead you to the same component.

Nonetheless, it demonstrates several fundamental principles of Angular routing:

  • In its most basic form, a route is comprised of a string path (matched against the browser path) and the component that should be rendered when this route is active.
  • Routes are installed via RouterModule. In this example, since there is only one module, you can do this once using forRoot(). However, keep in mind that you can break your routing structure into pieces and between different NgModules.
  • Navigating to a route will cause a component to be rendered inside a different component-more specifically, wherever the <router-outlet> tag exists. There are many ways in which this can be configured and made more complex, but for the purpose of this simple module, you don't need to worry about these different ways.

There's more...

Angular 2 applications will not raise issues when operating with no form of routing. If your application does not need to understand and manage the page URL, then feel free to totally discard the routing files and modules from your application.

Initial page load

The flow you are hoping your users would go through is as follows:

  1. The user visits .
  2. The server matches the empty route to index.html.
  3. The page loads, requesting static files.
  4. The Angular static files are loaded and application is bootstrapped.
  5. The user clicks on the links and navigates around the site.
  6. Since Angular is wholly managing the navigation and routing, everything works as expected.

This is the ideal case. Consider a different case:

  1. The user has already visited  before and bookmarked it.
  2. The user enters foo.com/bar in their URL bar and navigates to it from there directly.
  3. The server sees the request path as /bar and tries to handle the request.

Depending on how your server is configured, this might cause problems for you. This is because the last time the user visited foo.com/bar, no request for that resource reached the server because Angular was only emulating a real navigation event.

This scenario is discussed elsewhere in this chapter, but keep in mind that without a correctly configured server, the user in the second case might see a 404 page error instead of your application.

See also

  • Navigating with routerLinks demonstrates how to navigate around Angular applications
  • Navigating with the Router service uses an Angular service to navigate around an application
  • Building stateful RouterLink behavior with RouterLinkActive shows how to integrate application behavior with a URL state
Назад: 6. The Component Router
Дальше: Navigating with routerLinks

thank you
Flame
cant read the code since it is all on a single line. Also this comments section is russian
Rakuneque
DATA COLLECTION AND ANALYSIS Two reviewers extracted data and assessed methodological quality independently lasix torsemide conversion Many others were in that space already