Angular 2
маршрутизация
Поиск…
Основная маршрутизация
Маршрутизатор позволяет осуществлять навигацию с одного вида на другой на основе взаимодействия пользователя с приложением.
Ниже приведены шаги по реализации базовой маршрутизации в Angular 2 -
Основные меры предосторожности : убедитесь, что у вас есть тег
<base href='/'>
как первый ребенок под вашим тегом заголовка в вашем файле index.html. Этот тег сообщает, что папка вашего приложения является корнем приложения. Тогда Angular 2 будет знать, как организовать ваши ссылки.
Первый шаг - проверить, указали ли вы на исправление / последние зависимости маршрутизации в package.json -
"dependencies": {
......
"@angular/router": "3.0.0-beta.1",
......
}
Второй шаг - определить маршрут согласно определению класса -
class Route {
path : string
pathMatch : 'full'|'prefix'
component : Type|string
.........
}
В файле маршрутов ( route/routes.ts
) импортируйте все компоненты, которые необходимо настроить для разных маршрутов маршрутизации. Пустой путь означает, что представление загружается по умолчанию. «:» в пути указывает динамический параметр, переданный загруженному компоненту.
Маршруты становятся доступными для приложения через инъекцию зависимости. Метод ProviderRouter вызывается с параметром RouterConfig в качестве параметра, так что он может быть добавлен к компонентам для вызова определенных задач маршрутизации.
import { provideRouter, RouterConfig } from '@angular/router';
import { BarDetailComponent } from '../components/bar-detail.component';
import { DashboardComponent } from '../components/dashboard.component';
import { LoginComponent } from '../components/login.component';
import { SignupComponent } from '../components/signup.component';
export const appRoutes: RouterConfig = [
{ path: '', pathMatch: 'full', redirectTo: 'login' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'bars/:id', component: BarDetailComponent },
{ path: 'login', component: LoginComponent },
{ path: 'signup', component: SignupComponent }
];
export const APP_ROUTER_PROVIDER = [provideRouter(appRoutes)];
Третий шаг - загрузить загрузчика маршрута.
В вашем main.ts
(это может быть любое имя. В основном, это должен ваш основной файл, определенный в systemjs.config)
import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from './components/app.component';
import { APP_ROUTER_PROVIDER } from "./routes/routes";
bootstrap(AppComponent, [ APP_ROUTER_PROVIDER ]).catch(err => console.error(err));
Четвертый шаг - загрузить / отобразить компоненты маршрутизатора на основе доступа к пути. директива используется для указания угловой нагрузки для загрузки компонента. Использовать импорт ROUTER_DIRECTIVES.
import { ROUTER_DIRECTIVES } from '@angular/router';
@Component({
selector: 'demo-app',
template: `
....................................
<div>
<router-outlet></router-outlet>
</div>
....................................
`,
// Add our router directives we will be using
directives: [ROUTER_DIRECTIVES]
})
Пятый шаг - связать другие маршруты. По умолчанию RouterOutlet загрузит компонент, для которого пуст путь указан в RouterConfig. Директива RouterLink используется с тэгом html anchor для загрузки компонентов, подключенных к маршрутам. RouterLink генерирует атрибут href, который используется для создания ссылок. Для Ex:
import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';
@Component({
selector: 'demo-app',
template: `
<a [routerLink]="['/login']">Login</a>
<a [routerLink]="['/signup']">Signup</a>
<a [routerLink]="['/dashboard']">Dashboard</a>
<div>
<router-outlet></router-outlet>
</div>
`,
// Add our router directives we will be using
directives: [ROUTER_DIRECTIVES]
})
export class AppComponent { }
Теперь мы хорошо справляемся с маршрутизацией в статический путь. RouterLink поддерживает динамический путь, также передавая дополнительные параметры вместе с этим путем.
import {Component} из '@ angular / core'; import {ROUTER_DIRECTIVES} из '@ angular / router';
@Component({
selector: 'demo-app',
template: `
<ul>
<li *ngFor="let bar of bars | async">
<a [routerLink]="['/bars', bar.id]">
{{bar.name}}
</a>
</li>
</ul>
<div>
<router-outlet></router-outlet>
</div>
`,
// Add our router directives we will be using
directives: [ROUTER_DIRECTIVES]
})
export class AppComponent { }
RouterLink берет массив, где первый элемент - это путь для маршрутизации, а последующие элементы - для параметров динамической маршрутизации.
Детские маршруты
Иногда имеет смысл вставлять точки зрения или маршруты друг в друга. Например, на панели управления вам нужно несколько подзадач, похожих на вкладки, но реализованные через систему маршрутизации, чтобы показать проекты, контакты, сообщения и т. Д. Пользователей. Чтобы поддерживать такие сценарии, маршрутизатор позволяет нам определять дочерние маршруты.
Сначала мы корректируем RouterConfig
сверху и добавляем дочерние маршруты:
import { ProjectsComponent } from '../components/projects.component';
import { MessagesComponent} from '../components/messages.component';
export const appRoutes: RouterConfig = [
{ path: '', pathMatch: 'full', redirectTo: 'login' },
{ path: 'dashboard', component: DashboardComponent,
children: [
{ path: '', redirectTo: 'projects', pathMatch: 'full' },
{ path: 'projects', component: 'ProjectsComponent' },
{ path: 'messages', component: 'MessagesComponent' }
] },
{ path: 'bars/:id', component: BarDetailComponent },
{ path: 'login', component: LoginComponent },
{ path: 'signup', component: SignupComponent }
];
Теперь, когда мы определили наши дочерние маршруты, мы должны убедиться, что эти дочерние маршруты могут отображаться в нашем DashboardComponent
, так как именно там мы добавили дочерние элементы. Ранее мы узнали, что компоненты отображаются в <router-outlet></router-outlet>
. Аналогично, мы объявляем еще один RouterOutlet
в DashboardComponent
:
import { Component } from '@angular/core';
@Component({
selector: 'dashboard',
template: `
<a [routerLink]="['projects']">Projects</a>
<a [routerLink]="['messages']">Messages</a>
<div>
<router-outlet></router-outlet>
</div>
`
})
export class DashboardComponent { }
Как вы можете видеть, мы добавили еще один RouterOutlet
в котором будут отображаться дочерние маршруты. Обычно будет показан маршрут с пустым путём, однако мы перенаправляем маршрут projects
, потому что мы хотим, чтобы это было показано сразу же после загрузки маршрута dashboard
. При этом нам нужен пустой маршрут, иначе вы получите сообщение об ошибке:
Cannot match any routes: 'dashboard'
Таким образом, добавив пустой маршрут, то есть маршрут с пустым путем, мы определили точку входа для маршрутизатора.
ResolveData
В этом примере вы покажете, как вы можете разрешать данные, полученные из службы, перед представлением вашего приложения.
Использует угловой / маршрутизатор 3.0.0-beta.2 на момент написания
users.service.ts
... import { Http, Response } from '@angular/http'; import { Observable } from 'rxjs/Rx'; import { User } from './user.ts'; @Injectable() export class UsersService { constructor(public http:Http) {} /** * Returns all users * @returns {Observable<User[]>} */ index():Observable<User[]> { return this.http.get('http://mywebsite.com/api/v1/users') .map((res:Response) => res.json()); } /** * Returns a user by ID * @param id * @returns {Observable<User>} */ get(id:number|string):Observable<User> { return this.http.get('http://mywebsite.com/api/v1/users/' + id) .map((res:Response) => res.json()); } }
users.resolver.ts
... import { UsersService } from './users.service.ts'; import { Observable } from 'rxjs/Rx'; import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from "@angular/router"; @Injectable() export class UsersResolver implements Resolve<User[] | User> { // Inject UsersService into the resolver constructor(private service:UsersService) {} resolve(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<User[] | User> { // If userId param exists in current URL, return a single user, else return all users // Uses brackets notation to access `id` to suppress editor warning, may use dot notation if you create an interface extending ActivatedRoute with an optional id? attribute if (route.params['id']) return this.service.get(route.params['id']); return this.service.index(); } }
users.component.ts
Это компонент страницы со списком всех пользователей. Он будет работать аналогично для компонента детали детали пользователя, замените data.users
на data.user
или любой другой ключ, определенный в app.routes.ts (см. Ниже)
... import { ActivatedRoute} from "@angular/router"; @Component(...) export class UsersComponent { users:User[]; constructor(route: ActivatedRoute) { route.data.subscribe(data => { // data['Match key defined in RouterConfig, see below'] this.users = data.users; }); } /** * It is not required to unsubscribe from the resolver as Angular's HTTP * automatically completes the subscription when data is received from the server */ }
app.routes.ts
... import { UsersResolver } from './resolvers/users.resolver'; export const routes:RouterConfig = <RouterConfig>[ ... { path: 'user/:id', component: UserComponent, resolve: { // hence data.user in UserComponent user: UsersResolver } }, { path: 'users', component: UsersComponent, resolve: { // hence data.users in UsersComponent, note the pluralisation users: UsersResolver } }, ... ] ...
app.resolver.ts
Опционально объединить несколько резольверов вместе.
ВАЖНО: сначала необходимо импортировать службы, используемые в resolver, или вы получите «Нет провайдера для ошибки ..Resolver». Помните, что эти службы будут доступны во всем мире, и вам больше не нужно будет объявлять их providers
любого компонента. Обязательно отмените подписку на любую подписку, чтобы предотвратить утечку памяти
... import { UsersService } from './users.service'; import { UsersResolver } from './users.resolver'; export const ROUTE_RESOLVERS = [ ..., UsersService, UsersResolver ]
main.browser.ts
Резольверы должны вводиться во время начальной загрузки.
... import {bootstrap} from '@angular/platform-browser-dynamic'; import { ROUTE_RESOLVERS } from './app.resolver'; bootstrap(<Type>App, [ ... ...ROUTE_RESOLVERS ]) .catch(err => console.error(err));
Маршрутизация с детьми
В отличие от исходной документации, я нашел, что это способ правильно встраивать маршруты детей в файл app.routing.ts или app.module.ts (в зависимости от ваших предпочтений). Этот подход работает при использовании WebPack или SystemJS.
В приведенном ниже примере показаны маршруты для дома, дома / счетчика и данных home / counter / fetch. Первый и последний маршруты являются примерами перенаправления. Наконец, в конце примера приведен правильный способ экспорта маршрута, который должен быть импортирован в отдельный файл. Напр. app.module.ts
Для дальнейшего объяснения, Угловая требует, чтобы у вас был беспроблемный маршрут в массиве children, который включает в себя родительский компонент, для представления родительского маршрута. Это немного запутанно, но если вы думаете о пустом URL-адресе для детского маршрута, он по существу будет равен тому же URL-адресу, что и родительский маршрут.
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { HomeComponent } from "./components/home/home.component";
import { FetchDataComponent } from "./components/fetchdata/fetchdata.component";
import { CounterComponent } from "./components/counter/counter.component";
const appRoutes: Routes = [
{
path: "",
redirectTo: "home",
pathMatch: "full"
},
{
path: "home",
children: [
{
path: "",
component: HomeComponent
},
{
path: "counter",
children: [
{
path: "",
component: CounterComponent
},
{
path: "fetch-data",
component: FetchDataComponent
}
]
}
]
},
{
path: "**",
redirectTo: "home"
}
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
Отличный пример и описание через Siraj