Как перенаправить внешний 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. Это решение выглядит действительно странно для меня. Для такого случая это должно быть действительно легко реализовать без виртуальных компонентов.
Ответы
Ответ 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.