Route. Переключения и параметры
Route (роутинг)
В модуле:
import { Routes, RouterModule } from '@angular/router';
const appRoutes: Routes = [
{path: '', component: HomeComponent},
{path: 'users', component: UsersComponent},
{path: 'servers', component: ServersComponent},
];
imports: [
//...
RouterModule.forRoot(appRoutes)
],
В app.component.html
:
<div class="row">
<div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
<router-outlet>
</div>
</div>
Router links
Для ссылок роутера есть специальное свойство routerLink
, которое в отличие от href
не перезагружает страницу:
<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>
или:
<li role="presentation"><a [routerLink]="['/users']">Users</a></li>
Виды ссылок
- /link - абсолюный путь
- link или ./link - относительный путь
- ../../link - относительный путь с указанием вернуться на предыдущий уровень 2 раза
Стили ссылок роутера
<li
role="presentation"
routerLinkActive="active"
[routerLinkActiveOptions]="{exact: true}">
<a routerLink="/">Home</a>
</li>
<li
role="presentation"
routerLinkActive="active">
<a routerLink="/servers">Servers</a>
</li>
Свойство routerLinkActive
применяет указанный класс к активной ссылке.
Свойство [routerLinkActiveOptions]="{exact: true}"
применяется к ссылке на главную страницу '/'
, эта опция говорит о том, что совпадение url должно быть точным, иначе любая ссылка, содержащая /
будет расценена как домашняя и пункт Home
будет всегда активным.
Route (переключение и параметры)
Переключение роутера с помощью API
В компоненте:
//...
import { Router } from '@angular/router';
@Component({
//...
})
export class HomeComponent implements OnInit {
constructor(private router: Router) { }
...
onServerLoaded() {
//complex logic
this.router.navigate(['/servers']);
}
}
Относительная ссылка
В программном роутинге нельзя просто указать относительную ссылку, необходимо передать объект текущего роутера для построения ссылки относительно него:
//...
import { Router, ActivatedRoute } from '@angular/router';
@Component({
//...
})
export class ServersComponent implements OnInit {
//...
constructor(...
private router: Router,
private route: ActivatedRoute) { }
//...
go_to_rel_link() {
this.router.navigate(['servers'], {relativeTo: this.route});
}
}
Передача параметров в роутер
Для того, чтобы роутер сработал на произвольную часть url, как на шаблон, достаточно добавить двоеточие в path
, часть после двоеточия будет соответствовать чему угодно:
const appRoutes: Routes = [
//...
{path: 'users/:id', component: UserComponent},
//...
];
Получение параметров роутера
В модуле:
const appRoutes: Routes = [
{path: 'users/:id/:name', component: UserComponent},
//...
];
В компоненте:
//...
import { ActivatedRoute } from '@angular/router';
@Component({
//...
})
export class UserComponent implements OnInit {
user: {id: number, name: string};
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.user = {
id: this.route.snapshot.params['id'],
name: this.route.snapshot.params['name'],
}
}
}
Передача параметров и фрагментов запроса
Формирование ссылки вида /servers/2/edit?allowEdit=1#loading
:
<a
[routerLink] = "['/servers', server.id, 'edit']"
[queryParams] = "{allowEdit: '1'}"
fragment = 'loading'
*ngFor="let server of servers">
{{ server.name }}
</a>
Программно:
constructor(private router: Router) { }
this.router.navigate(
[
'/servers',
id,
'edit'
],
{
queryParams: {allowEdit: '1'},
fragment: 'loading'
}
);
Получение параметров url
//подключить класс
import { ActivatedRoute } from '@angular/router';
//инициализировать элемент класса
constructor(private route: ActivatedRoute) { }
//получить параметры и фрагмент (не реактивно)
this.route.snapshot.queryParams
this.route.snapshot.fragment
//подписаться (реактивно)
this.route.queryParams.subscribe(...);
this.route.fragment.subscribe(...);
Родительский роутинг
Дочерние роутинги создаются следующим образом. В app.module.ts
:
{path: 'servers', component: ServersComponent, children: [
{path: ':id', component: ServerComponent},
{path: ':id/edit', component: EditServerComponent},
]},
Пример использования параметров запроса
В шаблоне есть кнопка на редактирование данного элемента:
<button
class="btn btn-primary"
(click)="onEdit()">
Edit Server
</button>
Обработчик данного события выглядит так:
onEdit() {
this.router.navigate(['edit'], {relativeTo: this.route, queryParamsHandling: 'preserve'});
}
queryParamsHandling
важный параметр, который позволяет сохранять параметры url при переходе.
Компонент редактирования при инициализации подписывается на изменение параметров, и на основании параметров uri определяет значение своей переменной:
ngOnInit() {
this.route.queryParams.subscribe(
(queryParams: Params) => {
this.allowEdit = queryParams['allowEdit'] === '1';
}
);
//...
}
Редирект
Рассмотрим редирект на примере 404 страницы. Создадим настройку редиректа, нужно чтобы он находится в самом низу путей (параметры роутера в модуле) и совпадал с любым адресом. Таким образом, если запрос не соответствует запросам описанным выше, то он будет перенаправлен на страницу 404:
const appRoutes: Routes = [
//...
{path: 'page404', component: Page404Component},
{path: '**', redirectTo: '/page404'},
];
**
в примере выше означает соответствие чему угодно. Эта последовательность полезна для создания 404 страниц или редиректа к другим роутам.