204 lines
5.5 KiB
Markdown
204 lines
5.5 KiB
Markdown
# 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
|
|
|
|
```ts
|
|
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`
|
|
```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
|
|
```html
|
|
<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
|
|
```html
|
|
<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.
|
|
```html
|
|
<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.
|
|
|
|
```html
|
|
<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 `/`
|
|
|
|
```html
|
|
<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
|
|
```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.
|
|
```ts
|
|
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`
|
|
|
|
<img src="../img/fetching_route_params.png" alt="overview" width="500"/>
|
|
|
|
`id` = 1
|
|
|
|
`name` = Max
|
|
|
|
```ts
|
|
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.
|
|
|
|
```ts
|
|
ngOnDestroy() {
|
|
this.paramsSubscription.unsubscribe();
|
|
}
|
|
```
|
|
|
|
## Passing query parameters and fragments
|
|
|
|
`servers.component.html`
|
|
```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
|
|
|
|
```ts
|
|
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;
|
|
}
|
|
```
|
|
|