web-dev-qa-db-ja.com

Angular 2 routerとlocation.go()を使用して戻るボタンの押下を検出する方法は?

_router 3.0.0-beta.1_を使用してアプリセクションを切り替えるアプリを作成しました。また、location.go()を使用して、同じページのサブセクション間の切り替えをエミュレートします。ページの更新時にすべてのルートを_<base href="/">_にリダイレクトするために、_index.html_といくつかのURL書き換えルールを使用しました。これにより、ルーターは要求されたサブセクションをURLパラメーターとして受信できます。基本的に、HashLocationStrategyの使用を避けることができました。

routes.ts

_export const routes: RouterConfig = [
    {
        path: '',
        redirectTo: '/catalog',
        pathMatch: 'full'
    },
    {
        path: 'catalog',
        component: CatalogComponent
    },
    {
        path: 'catalog/:topCategory',
        component: CatalogComponent
    },
    {
        path: 'summary',
        component: SummaryComponent
    }
];
_

ナビゲーションバーのサブセクションをクリックすると、2つのことが起こります。

  • logation.go()は、現在のサブセクションを示すために必要な文字列でURLを更新します
  • カスタムscrollTo()アニメーションは、要求されたサブセクションの上部にあるページをスクロールします。

ページを更新すると、以前に定義したルートを使用して、要求されたサブセクションへのスクロールを復元するために必要なパラメーターを抽出します。

_this._activatedRoute.params
    .map(params => params['topCategory'])
    .subscribe(topCategory => {
        if (typeof topCategory !== 'undefined' &&
            topCategory !== null
        ) {
            self.UiState.startArrowWasDismised = true;
            self.UiState.selectedTopCategory = topCategory;
        }
    });
_

戻るボタンをクリックした場合を除き、すべて正常に動作します。前のページが別のセクションであった場合、アプリルーターは期待どおりに動作します。ただし、前のページ/ URLがサブセクションであった場合、URLは前のものに変わりますが、UIでは何も起こりません。 scrollTo()関数を呼び出して再び仕事をするために戻るボタンが押されたかどうかを検出するにはどうすればよいですか?

ほとんどの回答はイベントonhashchangeで見ましたが、URLにハッシュがないため、このイベントはアプリで発生しません...

12
Adrian Moisa

答えが日付付きかどうかはわかりませんが、最新のAngular=バージョンではうまくいきませんでした。私がしたことは、Angularコンポーネントにインポートすることにより、イベントリスナー:

import { HostListener } from '@angular/core';

そして、popstateオブジェクトでwindowをリッスンします(エイドリアンが推奨したように):

  @HostListener('window:popstate', ['$event'])
  onPopState(event) {
    console.log('Back button pressed');
  }

これは私のために働いた。

16
VSO

角度のドキュメントは、PlatformLocationクラスで直接述べています...

  • このクラスは、アプリケーション開発者が直接使用しないでください。

コンストラクターでLocationStrategyを使用しました

constructor(location: LocationStrategy) {
  location.onPopState(() => {
    alert(window.location);
  });
}
5
Rmalmoe

ブラウザの[戻る]ボタンを検出するには、 '@ angular/commonからplatformlocationをインポートし、コンストラクタに次のコードを配置します。

 constructor(location: PlatformLocation) {
     location.onPopState(() => {
        alert(window.location);
     }); }
5
Shivakumar NH

Adrian Moisaの回答に同意します。

ただし、クラス PlatformLocation を使用してコンポーネントまたはサービスにインジェクトすることにより、「more Angular 2 way」を使用できます。次に、この方法でonPopStateコールバックを定義できます。

this.location.onPopState(()=>{
  // your code here...
  this.logger.debug('onpopstate event');
});
3
vanrado

この問題の別の代替手段は、 Angular Router service によって発行されたイベントをサブスクライブすることです。ルーティングを扱っているため、ルーターイベントを使用する方が理にかなっているように思えます。

constructor(router: Router) {
    router.events
      .subscribe((event: NavigationStart) => {
        if (event.navigationTrigger === 'popstate') {
          // Perform actions
        }
      });
}

popstateは、ブラウザで前後に押すと発生することに注意してください。そのため、これを効率的に行うには、どちらが発生しているかを判断する方法を見つける必要があります。私にとっては、タイプ NavigationStarteventオブジェクトを使用するだけで、ユーザーがどこから来て、どこに行くのかについての情報を提供します。

3
Jon Black

きれいな方法は、rxjsから「fromEvent」をインポートして、この方法で使用することです。

fromEvent(window, 'popstate')
  .subscribe((e) => {
    console.log(e, 'back button');
  });
2
Ryann Galea

onpopstate eventを使用してトリックを行いました:

window.addEventListener('popstate',
    // Add your callback here
    () => self.events.scrollToTopCategory.emit({ categId: self.state.selectedTopCategory })
);
1
Adrian Moisa