Angular2ルーターの遅延ロード(AsyncRoute)とrouterCanDeactivateの使用方法を確認し、簡単なサンプルを作成しました。
※Angular2のβ版、TypeScriptを使って確認したものです。
(1)遅延ロード(AsyncRoute)
リファレンスマニュアルのサンプルはよく分からなかったため、以下記事を参照しました。
Lazy loading in Angular 2.0
@RouteConfigのルーティング設定でAsyncRouteを使って設定します。ユーザーがルーティング先としてリンクをクリックした時点で該当コンポーネントがロードされるので、アプリ起動時の負荷を軽減できます。
●サンプルコード
@Component({ selector: 'my-app', template: ` <ul class="nav nav-pills"> <a [routerLink]="['Home']">ホーム</a> <a [routerLink]="['Async']">遅延ロード</a> </ul> <router-outlet></router-outlet> `, directives: [ROUTER_DIRECTIVES], }) @RouteConfig([ { path: '/home', name: 'Home', component: HomeComponent, useAsDefault: true}, new AsyncRoute({ path: '/async', loader: () => System.import('./lazy-loaded.ts').then(c => c['LazyLoaded']), name: 'Async'}) ])
(2)routerCanDeactivate
●CanDeactivateインタフェース
・”routerCanDeactivate”ルートライフサイクルメソッドを定義する。
・”routerCanDeactivate”は、コンポーネントがナビゲーション操作で除去してよいかを確認する際にルーターによって呼び出される。
・”routerCanDeactivate”フックは、パラメータとして二つの”ComponentInstruction”を指定して呼び出される。二つのパラメータの一つ目は、ナビゲートされている現在のルート、二つ目のパラメーターが前のルートに該当する。
・”routerCanDeactivate”がfalseをリターンあるいはresolveした場合、ナビゲーションはキャンセルされる。trueの場合はナビゲーションが継続され、コンポーネントは非活性化され、除去される。
●ComponentInstruction
・一つのコンポーネント用のルートの状態を表す。
・”ComponentInstruction”のインスタンスは、”CanActivate”などのルートライフサイクルメソッドに渡される。
●サンプル
テキストボックスを編集中にブラウザの戻るボタンを押下すると編集内容を破棄してナビゲーションを続行するサンプル。
@Component({ selector: 'my-deact', template: ` <strong>routerCanDeactivateデモ</strong><br /> <p>編集状態でブラウザの戻るボタン押下で確認ダイアログ表示</p> <label>テストコメント: </label> <input [(ngModel)]="testnum"/> ` }) class DeactComponent implements CanDeactivate { routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) { if (!this.testnum) { return true; } return confirm('編集内容を破棄してよろしいですか?'); } }
(3)デモ
Angular : 2.0.0-beta.8
Bootstrap : 3.2.0
Loading…
<html> <head> <title>Angular 2 Demo</title> <base href="/sample/"> <script src="https://code.angularjs.org/2.0.0-beta.8/angular2-polyfills.js"></script> <script src="https://code.angularjs.org/tools/system.js"></script> <script src="https://code.angularjs.org/tools/typescript.js"></script> <script src="https://code.angularjs.org/2.0.0-beta.8/Rx.js"></script> <script src="https://code.angularjs.org/2.0.0-beta.8/angular2.dev.js"></script> <script src="https://code.angularjs.org/2.0.0-beta.8/router.dev.js"> <script> System.config({ transpiler: 'typescript', typescriptOptions: { emitDecoratorMetadata: true } }); System.import('./ts/app.ts').then(null, console.error.bind(console)); </script> <link rel="stylesheet" href="./css/bootstrap.min.css"> <link rel="stylesheet" href="./css/styles.css"> </head> <body> <div class="container"> <my-app>Loading...</my-app> </div> </body> </html>
メインコンポーネント
import {bootstrap} from 'angular2/platform/browser' import {Component} from 'angular2/core'; import {RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, AsyncRoute} from 'angular2/router'; import {CanDeactivate, ComponentInstruction} from 'angular2/router'; @Component({ selector: 'my-home', template: ` <strong>Home</strong><br /> ` }) class HomeComponent{ } @Component({ selector: 'my-deact', template: ` <strong>routerCanDeactivateデモ</strong><br /> <p>編集状態でブラウザの戻るボタン押下で確認ダイアログ表示</p> <label>テストコメント: </label> <input [(ngModel)]="testnum"/> ` }) class DeactComponent implements CanDeactivate { routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) { if (!this.testnum) { return true; } return confirm('編集内容を破棄してよろしいですか?'); } } @Component({ selector: 'my-app', template: ` <ul class="nav nav-pills"> <a [routerLink]="['Home']">ホーム</a> <a [routerLink]="['CanDeactivate']">CanDeactivate</a> <a [routerLink]="['Async']">遅延ロード</a> </ul> <router-outlet></router-outlet> `, directives: [ROUTER_DIRECTIVES], }) @RouteConfig([ { path: '/home', name: 'Home', component: HomeComponent, // useAsDefault: true}, }, { path: '/deact', name: 'CanDeactivate', component: DeactComponent}, new AsyncRoute({ path: '/async', loader: () => System.import('../../wp-content/themes/wp/ts/lazy-loaded.ts').then(c => c['LazyLoaded']), name: 'Async'}) ]) export class AppComponent{ } bootstrap(AppComponent, [ROUTER_PROVIDERS]); lazy-loaded.ts
import {Component} from 'angular2/core'; @Component({ selector: 'lazy-loaded', template: ` <p> 最初にルーティングされた時点でコンポーネントがロードされる。 </p> `, }) export class LazyLoaded { }