问题
I am trying to route in Angular2 Router based on the subdomain in a URL. For example if someone requests test.domain.com then they get the "test" route. I could not get router.navigate to work from ngOnInit without setting a timeout delay, but running the following from the constructor works. Would be interested if there was a cleaner solution ?
{path: 'test', component: TestComponent}
this._router.events.subscribe(event => {
if (event.constructor.name === 'NavigationEnd'
&& window.location.hostname == 'test.domain.com'
&& event.url == '/') {
console.log(event.url);
this._router.navigate(['test']);
}
});
回答1:
You may use Guards to prevent navigation or redirect to another path. Similar to your example:
@Injectable()
export class RedirectGuard implements CanActivate {
constructor(router:Router){}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
// check if need redirect
if (...) {
console.log(`requested url: ${state.url}`);
this.router.navigate(['/test']);
return false;
}
return true;
}
}
To apply the guard you should add it to module providers and to configure Route:
[{
path: '',
component: YourComponent,
canActivate: [RedirectGuard],
children...
},
{
path: 'test',
component: YourTestComponent,
children...
},
...
]
https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
Also I suppose that you could configure your application with different base href:
let useTestSubdomain: boolean = window.location.hostname == 'test.domain.com';
@NgModule({
providers: [{provide: APP_BASE_HREF, useValue: useTestSubdomain ? '/test' : '/'}]
})
class AppModule {}
https://angular.io/docs/ts/latest/api/common/index/APP_BASE_HREF-let.html
回答2:
You can use setTimeout as shown here,
ngOnInit() {
if (window.location.hostname == 'test.domain.com'){
console.log(window.location.hostname);
setTimeout(()=>{
this._router.navigate(['test']);
},2000)
}
};
回答3:
You can't do this by Nginx or domain proxy, or by Ingres, etc.
To solve this case you can use different global routes and insert them to routingModule by the condition of the current domain is loaded code bundle:
You will solve problem with duplicates of code, double applications, but only another model of routing with existing components inside one app.
// app.routing.ts
const TEST_routes: Routes = [
{
path: '',
component: TestPageComponent,
},
];
const PROJECT_routes: Routes = [
{
/// all needed routes of the whole main project
},
];
const isCurrentDomainTest: boolean =
(window.location.hostname === 'test.localhost') || // local
(window.location.hostname === 'test.yourdomain.com'); // prod
imports: [
RouterModule.forRoot(
isCurrentDomainTest ? TEST_routes : PROJECT_routes)
]
来源:https://stackoverflow.com/questions/39944026/angular2-routing-based-on-subdomain