Книга: Angular 2 Cookbook
Назад: Implementing nested views with route parameters and child routes
Дальше: Adding route authentication controls with route guards

Working with matrix URL parameters and routing arrays

Angular 2 introduces native support for an awesome feature that seems to be frequently overlooked: matrix URL parameters. Essentially, these allow you to attach an arbitrary amount of data inside a URL to any routing level in Angular, and giving you the ability to read that data out as a regular URL parameter.

Note

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

Getting ready

Begin with the code created at the end of the How to do it... section in Implementing nested views with route parameters and child routes.

Your goal is to pass arbitrary data to both the ArticleList and ArticleDetail levels of this application via only the URL.

How to do it...

routerLink arrays are processed serially, so any string that will become part of the URL that is followed by an object will have that object converted into matrix URL parameters. It will be easier to understand this by example, so begin by passing in some dummy data to the ArticleList view from routerLink:

[app/root.component.ts]      import {Component} from '@angular/core';      @Component({     selector: 'root',     template: `       <h1>Root component</h1>       <a [routerLink]="['']">          Default</a>       <a [routerLink]="['article', {listData: 'foo'}]">          Article</a>       <router-outlet></router-outlet>     `   })   export class RootComponent {}   

Now, if you click on this link, you will see your browser navigate to the following path while still successfully rendering the ArticleList view:

/article;listData=foo   

To access this data, simply extract it from the ActivatedRoute params:

[app/article-list.component.ts]      import {Component} from '@angular/core';   import {ActivatedRoute} from '@angular/router';      @Component({     template: `       <h3>Article List</h3>       <p *ngFor="let articleId of articleIds">         <a [routerLink]="[articleId]">           Article {{articleId}}         </a>       </p>     `   })   export class ArticleListComponent {     articleIds:Array<number> = [1,2,3,4,5];          constructor(private activatedRoute_:ActivatedRoute) {       activatedRoute_.params         .subscribe(params => {           console.log('List params:');           console.log(window.location.href)           console.log(params);         });     }   }   

When the view is loaded, you'll see the following:

List params:   /article;listData=foo   Object {listData: "foo"}   

Awesome! Do the same for the detail view:

[app/article-list.component.ts]      import {Component} from '@angular/core';   import {ActivatedRoute} from '@angular/router';      @Component({     template: `       <h3>Article List</h3>       <p *ngFor="let articleId of articleIds">         <a [routerLink]="[articleId, {detailData: 'bar'}]">           Article {{articleId}}         </a>       </p>     `   })   export class ArticleListComponent {     articleIds:Array<number> = [1,2,3,4,5];          constructor(private activatedRoute_:ActivatedRoute) {       activatedRoute_.params         .subscribe(params => {           console.log('List params:');           console.log(window.location.href)           console.log(params);         });     }   }   

Add the same amount of logging to the detail view:

[app/article-detail.component.ts]      import {Component} from '@angular/core';   import {ActivatedRoute} from '@angular/router';      @Component({     template: `       <h3>Article Detail</h3>       <p>Showing article {{articleId}}</p>       <a [routerLink]="'../'">Back up</a>     `   })   export class ArticleDetailComponent {     articleId:number;          constructor(private activatedRoute_:ActivatedRoute) {       activatedRoute_.params         .subscribe(params => {           console.log('Detail params:');           console.log(window.location.href)           console.log(params);                      this.articleId = params['articleId']         });     }   }   

When you visit a detail page, you'll see the following logged:

Detail params:   /article;listData=foo/1;detailData=bar   Object {articleId: "1", detailData: "foo"}   

Very interesting! Not only is Angular able to associate different matrix parameters with different routing levels, but it has combined both the expected articleId parameter and the unexpected detailData parameter into the same Observable emission.

How it works...

Angular is able to seamlessly convert from a routing array containing a matrix param object to a serialized URL containing the matrix params, then back into a deserialized JavaScript object containing the parameter data. This allows you to store arbitrary data inside URLs at different levels, without having to cram it all into a query string at the end.

There's more...

Notice that when you click on Back up in the detail view, the listData URL param is preserved. Angular will dutifully maintain the state as you navigate throughout the application, so using matrix parameters can be a very effective way of storing stateful data that survives navigation or page reloads.

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
  • Implementing nested views with route parameters and child routes gives an example of how to configure Angular URLs to support nesting and data passing
Назад: Implementing nested views with route parameters and child routes
Дальше: Adding route authentication controls with route guards

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