web-dev-qa-db-ja.com

コンポーネントを使用せずにangle2ルートから外部URLにリダイレクトする方法は?

外部リダイレクトを作成したいのですが、すべてのルートの一貫性を保つために、Router States構成ですべて(外部リダイレクトを含む)を行うのは良いことだと思います。

そう:

const appRoutes: Routes = [
  {path: '', component: HomeComponent},
  {path: 'first', component: FirstComponent},
  {path: 'second', component: SecondComponent},
  {path: 'external-link', /*would like to have redirect here*/}      
];

UPD:およびこの場合は空のコンポーネントを使用したくない like @ koningdavid推奨。このソリューションは、私にとって本当に奇妙に見えます。このような場合、仮想コンポーネントなしで実装するのは本当に簡単なはずです。

47

ルートの解決オプションを使用して、トリックで目的を達成できます。 Resolveは、Angular2がルートを初期化するために取得するデータ値です。詳細については、公式ドキュメントで here をご覧ください。

私はこのアプローチを試しましたが、うまくいきます。例:

これをプロバイダーセクションに追加します(さらに、ルーティングから必要なクラスをインポートします)。

@NgModule({
    providers: [
        {
            provide: 'externalUrlRedirectResolver',
            useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
            {
                window.location.href = (route.data as any).externalUrl;
            }
        }
    ]
})

次に、次のようにルートを定義できます。

{
        path: 'test',
        component: AnyRandomComponent,
        resolve: {
            url: 'externalUrlRedirectResolver'
        },
        data: {
            externalUrl: 'http://www.google.com'
        }
    }

これにより、外部URLにリダイレクトされます。それは本当にハック的な方法です。コンポーネントをまったく使用せずに結果を達成しようとしましたが、redirectToまたはcomponentまたはchildrenまたはloadChildrenを使用する必要があります。 redirectToは解決をトリガーせず、子供についてはわかりませんが、実験はできます。

プロバイダで直接機能するのではなく、Niceクラスで実装できます。ドキュメントの詳細(上記のリファレンスを参照)。

追伸私は本当に自分でリダイレクトコンポーネントを使用したいと思います。データでこのトリックを使用し、externalUrlでルーターから状態を取得するだけで、これをパラメーターとして取得できます。

59

RedirectGuardを作成できます。

import {Injectable} from '@angular/core';
import {CanActivate, ActivatedRouteSnapshot, Router, RouterStateSnapshot} from '@angular/router';

@Injectable()
export class RedirectGuard implements CanActivate {

  constructor(private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {

      window.location.href = route.data['externalUrl'];
      return true;

  }
}

App.moduleにインポートします:

providers: [RedirectGuard],

そして、ルートを定義します。

{
     path: 'youtube',
     canActivate: [RedirectGuard],
     component: RedirectGuard,
     data: {
       externalUrl: 'https://www.youtube.com/'
     }
 }
27

私の知る限り、NG2ルーターは外部リダイレクトをサポートしていません。回避策としてリダイレクトコンポーネントを作成できます。

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

@Component({
  selector: 'redirect',
  template: 'redirecting...'
})
export class RedirectComponent implements OnInit {
  constructor() { }

  ngOnInit() {
    window.location.href = 'http://www.redirecturl.com'
  }
}

ルーティングでそれを使用します

{ path: 'login', component: RedirectComponent, pathmath: 'full'},
16
koningdavid

うーん...

Ng2ルーターを呼び出す代わりに、単にURLを要求できると思います...


例えば...

<a href="http://example.com">External</a>

の代わりに

<a routerLink="/someRoute" routerLinkActive="active">External</a>

または

window.location.href = 'http://www.example.com'

の代わりに

this.router.navigate( [ '/someRoute', 'someParam' ] );

右...?

9
shramee

ルーターは外部にリダイレクトできません。外部リソースをアプリの状態にすることはできません。

わかりやすくするためだけに、すべてのルートを1つのスポットに表示したままにする場合は、ルートと同じファイル内のすべての外部パスで別の定数配列を定義できます。

4
Fiddles

私はあなたがすべての単一のURLのためにコンポーネントを作成したくないと仮定しています、それはあなたがコンポーネントなしでそれをすることを探している理由です...

そのため、コンポーネントオブジェクトを生成する関数を作成してみてください...

例えば...

function generateLinkingComponent( url ) {
  // Generate your component using koningdavid's code
  // replace 'http://www.redirecturl.com' with url param
  // and return it...
}

そして、このようにルーター設定に追加してください...

const appRoutes: Routes = [
  {path: '', component: HomeComponent},
  {path: 'first', component: FirstComponent},
  {path: 'second', component: SecondComponent},
  {path: 'external-link', component: generateLinkingComponent( 'http://example.com' )},
  {path: 'client-login', component: generateLinkingComponent( 'http://client-login.example.com' )},
  {path: 'admin-login', component: generateLinkingComponent( 'http://admin.example.com' )},
];

これはJSを使用すると簡単になりますが、TypeScriptの関数でクラスを返す方法がわかりません...

お役に立てば幸いです...

2
shramee

イリヤの答えをまとめる:

このモジュールを追加します。

import { Component, Injectable, NgModule } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve } from '@angular/router';

@Component({
  template: ''
})
class ExternalLinkComponent {
  constructor() {
  }
}

@Injectable()
class ExternalLinkResolver implements Resolve<any> {
  resolve(route: ActivatedRouteSnapshot): any {
    window.location.href = route.data.targetUri;
    return true;
  }
}

export class ExternalRoute {
  data: {
    targetUri: string;
  };
  path: string;
  pathMatch = 'full';
  resolve = { link: ExternalLinkResolver };
  component = ExternalLinkComponent;

  constructor(path: string, targetUri: string) {
    this.path = path;
    this.data = { targetUri: targetUri };
  }

}

@NgModule({
  providers: [ ExternalLinkResolver ],
  declarations: [ExternalLinkComponent]
})
export class ExternalRoutesModule { }

次にExternalRoutesModuleをインポートし、ExternalRouteのインスタンスを追加します。

const childRoutes: Routes = [
  new ExternalRoute('', '/settings/account'),
  { path: 'staff-profiles', component:  StaffProfilesComponent},
  { path: 'staff-assignments', component:  StaffAssignmentsComponent}
];

const routes: Routes = [
  { path: '', component: BaseComponent, children: childRoutes }
];

@NgModule({
  imports: [ ExternalRoutesModule, RouterModule.forChild(routes) ],
  exports: [ RouterModule ]
})
export class SettingsRoutingModule { }

この例では、loadChildrenを介してサブモジュールルートをマウントしています。

1
Sam