Angular 2ルーターで状態の変化をリッスンする方法は?
Angular 1.xでは、このイベントを使用しました。
$rootScope.$on('$stateChangeStart',
function(event,toState,toParams,fromState,fromParams, options){ ... })
したがって、Angular 2でこのイベントリスナを使用する場合:
window.addEventListener("hashchange", () => {return console.log('ok')}, false);
'ok'を返さず、JSから状態を変更してから、ブラウザのhistory.back()関数を実行します。
Router.subscribe()関数をサービスとして使用します。
import {Injectable} from 'angular2/core';
import {Router} from 'angular2/router';
@Injectable()
export class SubscribeService {
constructor (private _router: Router) {
this._router.subscribe(val => {
console.info(val, '<-- subscribe func');
})
}
}
ルーティングで初期化するコンポーネントにサービスを注入します。
import {Component} from 'angular2/core';
import {Router} from 'angular2/router';
@Component({
selector: 'main',
templateUrl: '../templates/main.html',
providers: [SubscribeService]
})
export class MainComponent {
constructor (private subscribeService: SubscribeService) {}
}
この例のような他のコンポーネントにこのサービスを注入します。次に、状態を変更し、サービス内のconsole.info()が機能しません。
私が間違っていることは何ですか?
新しいルーター
constructor(router:Router) {
router.events.subscribe(event:Event => {
if(event instanceof NavigationStart) {
}
// NavigationEnd
// NavigationCancel
// NavigationError
// RoutesRecognized
});
}
old
ルーターを挿入し、ルート変更イベントにサブスクライブします
import {Router} from 'angular2/router';
class MyComponent {
constructor(router:Router) {
router.subscribe(...)
}
}
NOTE
新しいルーターの場合は、NavigationStart
モジュールからrouter
をインポートすることを忘れないでください
import { Router, NavigationStart } from '@angular/router';
インポートしないとinstanceof
が機能せず、エラーNavigationStart is not defined
が発生するためです。
こちらもご覧ください
instanceof
を@GünterZöchbauerとして使用できます
this.router.events.subscribe(event => {
if(event instanceof NavigationStart) {
// do something...
}
}
または、lazierアプローチを使用できますが、コンストラクター名は、関数がまだ動作している間に簡単に変更できることに注意してください!
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
filter()
を使用してイベントをフィルタリングすることもできます。
しかし、justfilter(e => e is NavigationEnd)
を使用しないでください
より良い解決策は、次のようにfilter()
に 'type guard'を追加することです:
filter((e): e is NavigationEnd => e instanceof NavigationEnd),
次の2つが含まれます。
e is NavigationEnd
これは関数を定義しているアサーションです(これはTypeScript構文です)e instanceof NavigationEnd
これは、型をチェックする実際の実行時コードですこれの良い点は、以下のmap
のように、演算子が「パイプ」のさらに下にあることで、タイプがNavigationEnd
であることを知っていますが、タイプガードなしではタイプEvent
になります。
1つのイベントタイプのみをチェックする必要がある場合、これが最もクリーンな方法です。これは、コンパイラエラーを回避するために、厳格モードでも必要であると思われます。
angular2で、ファイル「app.modules.ts」-> importsに移動します
RouterModule.forRoot(
appRoutes,
{
enableTracing: true
}
)
enableTracingでtrueコンソールでrouteEventsを表示enableTracingでfalse falseコンソールでrouteEventsを非表示
angular 2ルーターイベントにはさまざまなクラスがあり、router.events
オブザーバブルからサブスクリプションに渡されるものは、NavigationEnd
、NavigationCancel
、NavigationError
、またはNavigationStart
のいずれかです。実際にルーティング更新をトリガーするのは、NavigationEnd
です。
minificationの後、クラス名が壊れて正しく動作しないため、instanceof
またはevent.constructor.name
の使用を避けます。
ここに示すように、代わりにルーターのisActive
関数を使用できます https://angular.io/docs/ts/latest/api/router/index/Router-class.html
this.routerEventSubscription = this._router.events.subscribe((event: any) => {
if (this._router.isActive(events.url, false)) {
// true if the url route is active
}
}