サーチ…


基本的なルーティング

ルーターは、アプリケーションとのユーザーのやりとりに基づいて、あるビューから別のビューへのナビゲーションを可能にします。

次に、基本的なルーティングを角度2で実装する手順を示します。

基本的な予防策 :タグがあることを確認してください

    <base href='/'> 

あなたのindex.htmlファイルのheadタグの下の最初の子として。このタグは、アプリケーションフォルダがアプリケーションルートであることを示します。 Angular 2はあなたのリンクを整理することを知っています。

最初のステップは、package.jsonの正しい/最新のルーティング依存関係を指しているかどうかを確認することです。

"dependencies": {
  ......
  "@angular/router": "3.0.0-beta.1",
  ......
}

2番目のステップは、クラス定義に従ってルートを定義することです。

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)];

第3のステップは、ルートプロバイダをブートストラップすることです。

あなたのmain.ts (それは任意の名前でも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));

第4のステップは、アクセスされたパスに基づいてルータコンポーネントをロード/表示することである。ディレクティブは、コンポーネントをロードする場所を指定するために使用されます。 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]
})

第5ステップは、他のルートをリンクすることです。デフォルトでは、RouterOutletは空のパスが指定されているコンポーネントをRouterConfigにロードします。 RouterLinkディレクティブはhtmlアンカータグとともに使用され、ルートに接続されたコンポーネントをロードします。 RouterLinkは、リンクを生成するために使用されるhref属性を生成します。例:

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は、パスとともに余分なパラメータを渡すことによっても動的パスをサポートします。

'@ angle / core'から{Component}をインポートします。 '@ angular / router'から{ROUTER_DIRECTIVES}をインポートします。

@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内に表示できるようにする必要があります.DashboardComponentは子ルートを追加した場所です。以前は、コンポーネントが<router-outlet></router-outlet>タグに表示されていることがわかりました。同様にDashboardComponent別の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

これはすべてのユーザーのリストを持つページコンポーネントです。 User detail pageコンポーネントでも同様にdata.usersし、 data.usersdata.userまたはdata.usersで定義されているキーに置き換えます (下記参照)

...
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エラーのプロバイダがありません」というメッセージが表示されます。これらのサービスは世界中で提供される予定であるため、コンポーネントの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を使用する場合に機能します。

次の例は、ホーム、ホーム/カウンタ、およびホーム/カウンタ/フェッチデータのルートを示しています。最初と最後のルートはリダイレクトの例です。最後に、例の最後に、別のファイルにインポートするルートをエクスポートする適切な方法があります。例えば、 app.module.ts

さらに説明すると、Angularでは、親ルートを表すために、親コンポーネントを含む子配列内にパスレスルートがあることが必要です。ちょっと混乱しますが、子ルートの空白の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