routing and navigation
TRANSCRIPT
Angular 2.0 Routing & Navigation
Eyal Vardi
Site: http://ng-course.org
Blog: eyalVardi.wordpress.com
Agenda Routes Configuration Routing Strategies RouterOutlet & RouterLink Directives Link Parameters Array Route Guards Lazy loaded modules
http://ev.com/
<router-outlet>
Component App
Home | Products | Users |
Products
<router-outlet>
Product 1
Product 2
Product 3
Product 4
Product 5
Product 6
Product 7
Product 8
products/product/1
<router-outlet>
Details | Price | Spec |
Tree State
root
home products
product
price spec
users
Routes Configuration The application will have one router. When the browser's URL changes, the router looks for a
corresponding Route from which it can determine the component to display.
export const appRoutes: Routes = [ { path:'home', component: HomeComponent }, { path:'products', component: ProductsComponent , children:[ { path: '' , component: NoneProductComponent }, { path: ':id' , component: ProductComponent} ] }, { path:'users', component: UsersComponent ,
children:[...] }];
Route Interface path pathMatch component redirectTo outlet data resolve
children loadChildren canLoad canActivate canActivateChild canDeactivate
Routing Strategies HashLocationStrategy ('#/') PathLocationStrategy (HTML 5 Mode)
@NgModule({
...
imports:[
RouterModule.forRoot(appRoutes, {useHash:true} ),
...
]
});
Path Location Strategy (HTML 5 Mode) Must set base URL. How to set the base URL, 3 options:
Providers:[{ provide : APP_BASE_HREF , useValue: '/' }]
<script> document.write( '<base href="' + document.location + '" />');</script>
<base href="/" >1.
2.
3.
RouterLink & RouterOutlet Directives
<router-outlet>
<a [routerLink]="['/Go']">Go</a>
Code : router.navigate( ['/Go'] );
HTML : <a [routerLink]="['/Go']">Go</a>
Component:
Template
<router-outlet>
Component App
Home | Products | Users |
Products
<router-outlet>
Product 1
Product 2
Product 3
Product 4
Product 5
Product 6
Product 7
Product 8
<router-outlet>
Details | Price | Spec |
<a [routerLink]="[ '
products ','product',{id:1}]">http://
ev.com/products/product/1
App
Products
Product
Link Parameters Array
['Products']
[routerLink]
['Products','Product']
[routerLink]
['./Product']
[routerLink]
[routerLink]
['/Products']
Query Parameters We use route parameters to specify a
parameterized value within the route URL. URL query Route parameters object{path:'/:id', component:Product}
<a [routerLink]="['product', {id:1}]">Product 1</a>
router.navigate(['product' ,'{id:8}']);
Getting The Route Parameter
@Component({...})export class User{ ... constructor( private route: ActivatedRoute ) {}
ngOnInit() { // Observable this.sub = this.route.params .map(params => params['id']) .subscribe( id => { this.selected = first; }); // snapshot // this.route.snapshot.params.id } ngOnDestroy() { this.sub.unsubscribe(); }}
the route params can change during the lifetime of this component.
Matrix URL Notation Matrix URL notation is an idea first floated in a 1996
proposal by the founder of the web, Tim Berners-Lee.
Although matrix notation never made it into the HTML standard, it is legal and it became popular among browser routing systems as a way to isolate parameters belonging to parent and child routes.
<a [routerLink]="['Product', {id:1,foo:3}]">Product 1</a>
localhost:3000/product/;id=1;foo=foo
RouteData
Route Guards
Route Interface path pathMatch component redirectTo outlet data resolve
children loadChildren canLoad canActivate canActivateChild canDeactivate
CanActivateexport interface CanActivate { canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot) :
Observable<boolean> | Promise<boolean> | boolean;}
@Injectable()export class AuthGuard implements CanActivate { canActivate() { console.log('AuthGuard#canActivate called'); return true; }}
{ path: 'admin', component: AdminCmp, canActivate: [AuthGuard] }
// Route config
CanDeactivateexport interface CanDeactivate<T> { canDeactivate(
component: T, route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<boolean> | Promise<boolean> | boolean;}
@NgModule({ imports: [ RouterModule.forRoot([{ path: 'team/:id', component: TeamCmp, canActivate: ['canDeactivateTeam'] }])], providers: [{ provide: 'canDeactivateTeam', useValue: (route:ActivatedRouteSnapshot, state:RouterStateSnapshot) => true}]})class AppModule {}
View I
Cancelling Route Changes
View IICancel
OK
routerCanDeactivate(){ return new Promise<boolean>((resolve, reject) => resolve(window.confirm('Continue?')));}
Resolve: pre-fetching dataclass Backend { fetchTeam(id: string){ return 'someTeam'; } }
@Injectable()class TeamResolver implements Resolve<Team> { constructor(private backend: Backend) {}
resolve( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ){ return this.backend.fetchTeam(route.params.id); }}
@NgModule({ imports: [ RouterModule.forRoot([{ path: 'team/:id', component: TeamCmp, resolve: { team: TeamResolver } }])], providers: [TeamResolver]})class AppModule {}
Lazy Loaded Modules The AppModule (root,home,users) load
when the application bootstrap.
The ProductsModule load whenwe navigate to‘/products’
root
home products
product
price spec
users
Load Childrenexport const appRoutes: Routes = [ { path:'home', component: HomeComponent }, { path:'products', loadChildren: 'app/products.module.js#ProductsModule'}, { path:'users', component: UsersComponent ,
children:[...] }];
export const productsRoutes: Routes = [ { path:'', component: ProductsComponent , children:[ { path: '' , component: NoneProductComponent }, { path: ':id' , component: ProductComponent} ] }];
// products.module.js
Thankseyalvardi.wordpress.com
Eyal Vardi
Site: http://ng-course.org
Blog: eyalVardi.wordpress.com