首页 文章

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

提问于
浏览
35

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

所以:

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

建议使用 UPD :和 I don't want to use empty component for this case 之类的 @koningdavid . 对我来说这个解决方案看起来很奇怪 . 对于没有虚拟组件的情况,这应该是非常容易实现的 .

7 回答

  • 47

    您可以使用路线的resolve选项通过技巧实现您想要的效果 . 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 . 这真的是一种hackish的方式 . 我试图在不使用组件的情况下实现结果,但您必须使用 redirectTocomponentchildrenloadChildren . redirectTo 不会触发决心,我不确定孩子,虽然你可以试验 .

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

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

  • 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'
      }
    }
    

    并在您的路由中使用它

    { path: 'login', component: RedirectComponent, pathmath: 'full'},
    
  • 2

    您可以创建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/'
         }
     }
    
  • 4

    嗯...

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


    例如...

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

    代替

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

    OR

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

    代替

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

    对...?

  • 1

    路由器无法从外部重定向 . 外部资源不能是应用程序的状态 .

    如果仅为了清晰起见,保持所有路径在一个点中可见,则可以定义另一个常量数组,其中所有外部路径与路径在同一文件中 .

  • 9

    我假设你不想为每个网址创建一个组件,这就是为什么你要在没有组件的情况下做这个...

    所以你可以尝试创建一个为你生成组件对象的函数...

    例如...

    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函数中返回一个类...

    希望有帮助......

  • 16

    结束伊利亚的回答:

    添加此模块 .

    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挂载子模块路由 .

相关问题