2016-06-23 5 views
2

同じミニページの2つのミニアプリがあります。 (ロングストーリー。)1つはナビゲーションアプリ、もう1つはメインアプリです。私はangular/vladivostokに基づいて最新の角度ルータを使用しています。Angular2ルータのnavigateByUrl()がngOnInit()を呼び出さない

他のアプリ(メインアプリなど)によってインスタンス化されたURLの変更に、あるアプリ(たとえばnav)の角度ルータが応答しないようです。だから私は両方のアプリケーションに提供するRouterSynchronizer クラスを作成しました。両方のルータの 'NavigationEnd'イベントを待ち受けます。 1つのルータ(「発信元」と呼ぶ)がイベントを持っている場合、他のルータのnavigateByUrl(「加入者」と呼ぶ)を呼び出します。

これはほとんどの場合、正常に動作します。ただし、サブスクライバのコンポーネントにはngOnInitが呼び出されません。

Angularの公式Routing & Navigation guideのライブサンプルに基づいて、これを示すためにa Plunkを作成しました。メインアプリで「Crisis Center」リンクと「Heroes」リンクをクリックすると、navコンポーネントの対応する子コンポーネントでngOnInitが呼び出されないことに注意してください。ただし、navコンポーネント内のリンクをクリックすると、ngOnInitとなりますが、主アプリの子コンポーネントのではなくとなります(英雄/危機センターのリストが空になります)。

アイデア?ありがとう!

RouterSynchronizerクラス:

import { Inject } from '@angular/core'; 
import { NavigationEnd, Router } from '@angular/router'; 

interface ISubscriber { 
    id: string; 
    router: Router; 
} 

export class RouterSynchronizer { 
    private subscribers: ISubscriber[] = []; 

    connect(id: string, router: Router): void { 
    this.subscribers.push({ id, router }); 
    this.startPublishing(id, router); 
    } 

    private startPublishing(source: string, router: Router): void { 
    router.events.subscribe(route => { 
     if (route instanceof NavigationEnd) { 
     this.subscribers.forEach(subscriber => { 
      if (subscriber.id === source || subscriber.router.url === route.urlAfterRedirects) { 
      // Prevent infinite loops. 
      return; 
      } 

      subscriber.router.navigateByUrl(route.urlAfterRedirects); 
     }); 
     } 
    }); 
    } 
} 

答えて

3

は、私はそれを考え出しました!明らかに、私はゾーンを使用する必要がありました。実装については、the new Plunkを参照してください。

問題(私は思う!)は、私のRouterSynchronizerクラスがインスタンス化され、角度コンテキストの外で提供されているということです。したがって、それがnavigateByUrl経由でルーターに変更をプッシュしたとき、それは角度ゾーンにはありませんでした。いったん私はnavigateByUrlの呼び出しをのアプリケーションで提供してくれました:

+2

イベントを発行するメソッドが別のAngularインスタンスで生成され、インスタンスはそれについて知りません。 'zone 'を使う必要があります。現在のAngular2アプリケーションのゾーン内でコードを実行させるようにrun(()=> {})を実行します。 –

-1

あなたはとても似のOnInitを実装する必要があります。

import { Component, OnInit } from '@angular/core'; 

@Component({ 
    selector: 'nav-heroes', 
    template: `<span *ngIf="hasRunOnInit">ngOnInit has run in NavCrisisCenterComponent</span>`, 
}) 

export class NavCrisisCenterComponent implements OnInit { 
    private hasRunOnInit: boolean; 

    ngOnInit() { 
    this.hasRunOnInit = true; 
} 
} 
+0

'' OnInit'を追加することをお勧めしますか?これは実際に実行時の効果はありません。どのようなメソッドを実装しているかを示すTypeScriptコンパイラの指標に過ぎません。 – jessepinho

+0

私はあなたのプロジェクトを実行し、OnInitを実装してくれました。 – Ron

+0

これを実装することで、ライフサイクルフックに触れることができます。そうしないと、OnInitは単なる別の機能に過ぎません。 Ref:https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#spy – Ron

関連する問題