如何在不使用组件的情况下从angular2路由重定向到外部URL?

Yar*_*dov 54 javascript angular2-routing angular

我想创建一个外部重定向,但为了使所有路由保持一致,我认为在路由器状态配置下做所有事情(包括外部重定向)会很好.

所以:

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

UPD:我不想像@koningdavid建议的那样使用空组件.对我来说这个解决方案看起来很奇怪.对于没有虚拟组件的情况,这应该是非常容易实现的.

Ily*_*dik 66

您可以使用路线的resolve选项通过技巧实现您想要的效果.Resolve是Angular2将为要初始化的路由获取的一些数据值.更多详细信息,你可以找到这里的官方文档.

我尝试过这种方法,但确实有效.例:

将其添加到提供程序部分(再从路由导入所需的类)

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

然后你可以像这样定义你的路线:

{
        path: 'test',
        component: AnyRandomComponent,
        resolve: {
            url: 'externalUrlRedirectResolver'
        },
        data: {
            externalUrl: 'http://www.google.com'
        }
    }
Run Code Online (Sandbox Code Playgroud)

这将重定向到外部URL.这真的是一种hackish的方式.我试图在不使用组件的情况下实现结果,但你必须使用redirectTo或者component或者children或者loadChildren.redirectTo虽然你可以试验,但不会触发决心,我不确定孩子.

您可以在一个很好的类中实现它,而不是在提供程序中直接执行它.文档中的更多信息(参见上面的参考资料).

PS我真的宁愿自己使用重定向组件.只需使用数据技巧并从路由器获取状态,将externalUrl其作为参数.


小智 35

您可以创建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;

  }
}
Run Code Online (Sandbox Code Playgroud)

在app.module中导入它:

providers: [RedirectGuard],
Run Code Online (Sandbox Code Playgroud)

并定义您的路线:

{
     path: 'youtube',
     canActivate: [RedirectGuard],
     component: RedirectGuard,
     data: {
       externalUrl: 'https://www.youtube.com/'
     }
 }
Run Code Online (Sandbox Code Playgroud)

  • 这实际上比公认的答案要好得多。使用 Guard/CanActivate 意味着您可以取消角度导航。如果您在新窗口中打开外部链接,这很重要,因为您可以多次点击链接,而不必显示空/noop 组件。完整示例:https://gist.github.com/SimplGy/64f9e64afd4d7af2e6e9befced7878c1 (2认同)
  • 可能是`return false` 是更合乎逻辑的返回语句吗? (2认同)
  • 太棒了,很适合我。但我想在标头中放置一个不记名令牌,因为我需要它到另一边,谢谢? (2认同)
  • @Gargoyle 感谢您的回复 - 它有帮助。我不知道为什么你有 **AppModule** 的 ***providers*** 并使用 ***providedIn***。它无需将其添加到 AppModule 即可工作。再次感谢! (2认同)

kon*_*vid 16

据我所知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'
  }
}
Run Code Online (Sandbox Code Playgroud)

并在您的路由中使用它

{ path: 'login', component: RedirectComponent, pathmath: 'full'},
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,但我需要不使用组件.没有组件创建的主要想法. (3认同)
  • 路由器无法从外部重定向.它没有意义,因为外部资源实际上不能成为应用程序的状态. (2认同)

shr*_*mee 9

嗯...

我想你可以简单地请求URL而不是调用ng2 Router ...


例如...

<a href="http://example.com">External</a>
Run Code Online (Sandbox Code Playgroud)

代替

<a routerLink="/someRoute" routerLinkActive="active">External</a>
Run Code Online (Sandbox Code Playgroud)

要么

window.location.href = 'http://www.example.com'
Run Code Online (Sandbox Code Playgroud)

代替

this.router.navigate( [ '/someRoute', 'someParam' ] );
Run Code Online (Sandbox Code Playgroud)

对...?


Lui*_*iro 6

只需使用:

{
    path: 'external-link',
    loadChildren: () => new Promise( () => { if(window.location.href.match(/external-link/) ) window.location.href = 'https://external-link.com/'; } ) 
  },
Run Code Online (Sandbox Code Playgroud)