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