Подтвердить что ты не робот

Как перенаправить внешний URL из маршрута angular2 без использования компонента?

Я хотел бы создать внешнюю переадресацию, но чтобы все маршруты были согласованы, я думаю, было бы неплохо сделать все (включая внешние переадресации) в конфигурации состояний маршрутизатора.

так:

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

UPD: и Я не хочу использовать пустой компонент для этого случая, например @koningdavid. Это решение выглядит действительно странно для меня. Для такого случая это должно быть действительно легко реализовать без виртуальных компонентов.

4b9b3361

Ответ 1

Вы можете достичь того, чего хотите, с помощью трюка, используя параметр разрешения маршрута. Решение - это некоторое значение данных, которое Angular2 будет получать для инициализации маршрута. Более подробную информацию вы можете найти здесь в официальной документации.

Я пробовал этот подход, и он работает. Пример:

Добавьте это в раздел поставщика (плюс импортируйте требуемые классы из маршрутизации)

@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 не приведет к решению, и я не уверен в отношении детей, хотя вы можете экспериментировать.

Вы можете реализовать его в хорошем классе, а не в прямой функции в провайдере. Дополнительная информация в документации (см. Ссылку выше).

P.S. Я бы предпочел использовать компонент переадресации, я думаю. Просто используйте трюк с данными и получая состояние от маршрутизатора с помощью externalUrl, чтобы получить это как параметр.

Ответ 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/'
     }
 }

Ответ 3

Насколько я знаю, маршрутизатор 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'},

Ответ 4

Хм...

Я думаю, вы можете просто запросить URL вместо вызова ng2 Router...


Например...

<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' ] );

Право...

Ответ 5

Маршрутизатор не может перенаправлять извне. Внешний ресурс не может быть состоянием приложения.

Если только для ясности, сохраняя все маршруты видимыми в одном месте, вы можете определить другой постоянный массив со всеми внешними путями в том же файле, что и маршруты.

Ответ 6

Я предполагаю, что вы не хотите создавать компонент для каждого URL-адреса, поэтому вы хотите сделать это без компонента...

Итак, вы можете попробовать создать функцию, которая генерирует объект компонента для вас...

Например...

function generateLinkingComponent( url ) {
  // Generate your component using koningdavid 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...

Надеюсь, что это поможет...

Ответ 7

Завершение ответа Илья:

Добавьте этот модуль.

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.