我想创建一个外部重定向,但为了使所有路由保持一致,我认为在路由器状态配置下做所有事情(包括外部重定向)会很好。
这样:
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 建议。对我来说这个解决方案看起来很奇怪。对于没有虚拟组件的情况,这应该是非常容易实现的。
答案 0 :(得分:53)
您可以使用路线的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的方式。我试图在不使用组件的情况下实现结果,但您必须使用redirectTo
或component
或children
或loadChildren
。 <{1}}不会触发决心,我不确定孩子,虽然你可以试验。
您可以在一个很好的类中实现它,而不是在提供程序中直接执行它。文档中的更多信息(参见上面的参考资料)。
P.S。我想我自己宁愿使用重定向组件。只需使用数据技巧并通过redirectTo
从路由器获取状态即可将其作为参数。
答案 1 :(得分:20)
您可以创建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/'
}
}
答案 2 :(得分: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'},
答案 3 :(得分:8)
嗯...
我认为你可以简单地请求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' ] );
右键...?
答案 4 :(得分:4)
路由器无法从外部重定向。外部资源不能是应用程序的状态。
如果只是为了清晰起见,保持所有路线在一个地点可见,你可以定义另一个常数阵列,其中所有外部路径与路线在同一个文件中。
答案 5 :(得分:2)
我认为你不想为每个网址创建一个组件,这就是为什么你不想在没有组件的情况下这样做的原因......
所以你可以尝试创建一个为你生成组件对象的函数......
例如......
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函数中返回一个类...
希望有帮助...
答案 6 :(得分:1)
结束伊利亚的回答:
添加此模块。
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挂载子模块路径。
答案 7 :(得分:0)
您可以使用 NavigationEnd 事件。
从“ @ angular / router”导入{NavigationEnd,Router};
app.component.ts
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
if (event.url.includes('faq')) {
// open in the same tab:
window.location.href = 'https://faq.website.com';
// open a new tab:
// window.open('https://faq.website.com', '_blank');
// and redirect the current page:
// this.router.navigate(['/']);
}
}
});
PS 。别忘了从AppRoutingModule中删除路线。
答案 8 :(得分:0)
只需使用:
{
path: 'external-link',
loadChildren: () => new Promise( () => { if(window.location.href.match(/external-link/) ) window.location.href = 'https://external-link.com/'; } )
},
答案 9 :(得分:0)
这是一个应该可以为您工作而不会出现很多问题的代码。仅供参考,路由器事件错误处理程序可以放在任何位置,而不管组件中的位置如何。
app.component.html
Angular Port is in 4200
<a routerLink="/test">Main Link - 1</a> |
<a [routerLink]="getLinkWithExternal({url: '/test', external:false})">Other Link - 1a</a> |
<a [routerLink]="getLinkWithExternal({url: 'http://localhost:4211', external:true})">Other Link - 1b</a> |
<a [routerLink]="getLink({url: '/test'})">Other Link - 1a</a> |
<a [routerLink]="getLink({url: 'http://localhost:4211'})">Other Link - 1b</a> |
<a style="cursor: pointer; text-decoration: underline;" (click)="routeLink('/test')">Other Link - 1c</a> |
<a style="cursor: pointer; text-decoration: underline;" (click)="routeLink('http://localhost:4211')">Other Link - 1d</a>
<router-outlet></router-outlet>
app.component.ts
import { Component } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
constructor(private router: Router) { }
// RECOMMENDATION - Add following in menus of each microservice (individual and different)
// external: true
// Will make it a better menu structure for each microservice
// If Single and same menu for all microservices then remove external === true
// Logic One
getLinkWithExternal(sidebarnavLink: any) {
this.router.errorHandler = function (error: any) {
if (!sidebarnavLink.url.includes(window.location.origin.toString()) && sidebarnavLink.url.includes("http") && sidebarnavLink.external === true) {
window.location.href = sidebarnavLink.url.toString();
return true;
}
return null;
}.bind(sidebarnavLink);
return [sidebarnavLink.url];
}
getLinkWithExternalWithEventSubscribe(sidebarnavLink: any) {
this.router.events.subscribe(function (event) {
if (event instanceof NavigationEnd) {
if (event.url.includes('http')) {
if (!sidebarnavLink.url.includes(window.location.origin.toString()) && sidebarnavLink.url.includes("http") && sidebarnavLink.external === true) {
window.location.href = sidebarnavLink.url.toString();
return true;
}
return this.router.navigateByUrl(sidebarnavLink.url);
// return this.router.navigate([sidebarnavLink.url]);
}
return this.router.navigateByUrl(sidebarnavLink.url);
// return this.router.navigate([sidebarnavLink.url]);
}
}.bind(sidebarnavLink))
}
getLinkWithExternalImplementationTwoWithNoRouteError(sidebarnavLink: any) {
if (!sidebarnavLink.url.includes(window.location.origin.toString()) && sidebarnavLink.url.includes("http") && sidebarnavLink.external === true) {
window.location.href = sidebarnavLink.url.toString();
return true;
}
return [sidebarnavLink.url];
}
// Logic Two
getLink(sidebarnavLink: any) {
this.router.errorHandler = function (error: any) {
if (!sidebarnavLink.url.includes(window.location.origin.toString()) && sidebarnavLink.url.includes("http")) {
window.location.href = sidebarnavLink.url.toString();
return true;
}
return null;
}.bind(sidebarnavLink);
return [sidebarnavLink.url];
}
// Logic Three
routeLink(lnk: any) {
if (lnk.includes("http")) {
console.log("Test");
window.location.href = lnk;
return true;
}
return this.router.navigateByUrl(lnk);
// return this.router.navigate([lnk]);
}
}