Поиск…


Основная маршрутизация

Маршрутизатор позволяет осуществлять навигацию с одного вида на другой на основе взаимодействия пользователя с приложением.

Ниже приведены шаги по реализации базовой маршрутизации в 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



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow