5.5 KiB
Routing
Routes are a method to replace part of a page and display in the URL the desired component.
Setup and Loading Routes
In the app.module.ts
we need to register all the needed routes
import { Routers, RouterModule } from '@angular/router';
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'users', component: UsersComponent }, //localhost:4200/users
{ path: 'servers', component: ServersComponent },
];
@ngModule({
imports: [
...,
RouterModule.forRoot(appRoutes)
]
})
app.component.html
...
<!-- here we mark where we want to have the component rendered -->
<router-outlet></router-outlet>
...
Navigating with router links
With every klicked Link, a new request is sent to the server and the page is refreshed.
Bad implementation
<ul class="nav nav-tabs">
<li role="presentation" class="active"><a href="/">Home</a></li>
<li role="presentation"><a href="/servers">Servers</a></li>
<li role="presentation"><a href="/users">Users</a></li>
</ul>
Correct implementation
<ul class="nav nav-tabs">
<li role="presentation" class="active"><a routerLink="/">Home</a></li>
<li role="presentation"><a routerLink="/servers">Servers</a></li>
<li role="presentation"><a routerLink="/users">Users</a></li>
</ul>
If there is more then one level the routeLink will look like this and it's called array-notation.
<ul class="nav nav-tabs">
<li role="presentation" class="active"><a routerLink="/">Home</a></li>
<li role="presentation"><a routerLink="/servers">Servers</a></li>
<li role="presentation"><a [routerLink]="['/users', 'editUser'">Users Edit</a></li>
</ul>
Result: https://domain.tld/user/editUser
Relative path: servers
→ Relative path will be added to the actual path.
Absolute path: /servers
Styling active router links
routerLinkActive="active"
With active
is the CSS-Class to style the active nav element.
<ul class="nav nav-tabs">
<li role="presentation"
routerLinkActive="active"><a routerLink="/">Home</a></li>
<li role="presentation"
routerLinkActive="active"><a routerLink="/servers">Servers</a></li>
<li role="presentation"
routerLinkActive="active"><a routerLink="/users">Users</a></li>
</ul>
This method has a caviat, that angular analyzes the URL and the Home is allways active because in every route contains the domain.tld/
By adding the [routerLinkActiveOptions]="{exact: true}"
configuration, we can fix this issue. Necessary only on the /
<ul class="nav nav-tabs">
<li role="presentation"
routerLinkActive="active"
[routerLinkActiveOptions]="{exact: true}"><a routerLink="/">Home</a></li>
...
</ul>
Trigger the routing programmatically
In any Component ts
import { Router } from '@angular/router'
export class HomeComponent {
// inject of the router
constructor(private router: Router) {}
onLoadServer() {
// some calc
this.router.navigate(['servers']);
}
}
Passing parameter to Router
:id
wil be dynamically assigned.
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'users', component: UsersComponent }, //localhost:4200/users
{ path: 'users/:id', component: UserComponent }, //localhost:4200/users/5
{ path: 'servers', component: ServersComponent },
{ path: 'servers/:id', component: ServerComponent },
];
Fetching Route Parameters
The data will be fetched from the URL https://domain.tld/users/1/Max
id
= 1
name
= Max
this.route.snapshot.params.subscribe(
(params: Params) => {
this.user.id = params['id'];
this.user.name = params['name'];
}
);
If a route will change, the content of the Component will stay the same, because was allredy instanciated. If we want that the Component will update if the URL updates the route.params
has to be used. It is of type observable
and will act as asynchronus to load the data if and when the URL is changed.
If an instance gets destroyed and contains an observable which the component is subscribed to, is good practice to unsubscribe from it.
ngOnDestroy() {
this.paramsSubscription.unsubscribe();
}
Passing query parameters and fragments
servers.component.html
<a
[routerLink]="['/servers', server.id]"
[queryParams]="{allowEdit: server.id === 3 ? '1' : '0'}"
fragment="loading"
href="#"
class="list-group-item"
*ngFor="let server of servers">
{{ server.name }}
</a>
Retieving query parameters and fragments
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';
@Component({
selector: 'app-edit-server',
templateUrl: './edit-server.component.html',
styleUrls: ['./edit-server.component.css']
})
export class EditServerComponent implements OnInit, CanComponentDeactivate {
server: {id: number, name: string, status: string};
serverName = '';
serverStatus = '';
constructor(private serversService: ServersService,
private route: ActivatedRoute) {
}
ngOnInit() {
console.log(this.route.snapshot.queryParams);
console.log(this.route.snapshot.fragment);
this.server = this.serversService.getServer(id);
this.serverName = this.server.name;
this.serverStatus = this.server.status;
}