Перенаправить все URL-адреса с хэшем на угловые маршруты без хэша
Я заменяю существующий AngularJS 1.6.x SPA на Angular 5.x SPA и хочу сделать это изменение прозрачным для моих пользователей.
Я беспокоюсь о пользователях, у которых есть закладки для существующего приложения, потому что оно имеет хэши в URL (например: example.com/#/menu
а также example.com/#/item/37
);
Тем не менее, новое приложение не имеет хэши в URL (например: example.com/menu
а также example.com/item/37
).
Пути и маршрутизация одинаковы, за исключением #/
в текущем приложении.
Есть ли способ, которым я могу настроить угловую маршрутизацию, чтобы сбросить #/
и использовать конфигурацию маршрутизации без хэша нового приложения?
Я мог бы продублировать всю мою маршрутизацию для размещения путей с хешем и без него, но должен быть способ, который не требует удвоения моего кода.
// Don't really want to do this:
const routes: Routes = [
{
path: 'menu',
component: MenuComponent
},
{
path: '#/menu',
component: MenuComponent
},
// etc.
];
Точно так же, перенаправление каждого #/
путь будет удваивать код тоже.
// Don't really want to do this:
const routes: Routes = [
{
path: 'menu',
component: MenuComponent
},
{
path: '#/menu',
redirectTo: 'menu'
},
// etc.
];
Я надеюсь, что есть что-то вроде этого:
{
path: '#/*',
redirectTo: '*' // Somehow reference the wildcard part of the path here
}
Заранее спасибо за вашу помощь.
3 ответа
Ответ, опубликованный @Yanis, почти сработал, но потребовал несколько небольших изменений. Его ответ определенно заслуживает одобрения; однако ниже приведено рабочее решение, которое я реализовал:
export class AppComponent implements OnInit {
constructor (private router: Router) { }
ngOnInit() {
this.router.events.subscribe(event => {
if (event instanceof NavigationStart) {
if (!!event.url && event.url.match(/^\/#/)) {
this.router.navigate([event.url.replace('/#', '')]);
}
}
});
}
}
Я не знаю, если это правильный способ сделать это. Но вы можете сделать что-то вроде этого: цель состоит в том, чтобы подписаться на NavigationChange, затем вы проверяете, начинается ли ваш текущий маршрут с "#!", Если да, вы перенаправляете на правильный маршрут.
class AppComponent implement OnInit {
constructor(router: Router) {
//When url change, we check if actual url have #! on it, then we redirect to the route without it.
router.events.subscribe((event: NavigationEvent): void => {
this.url = router.url;
if (this.url.match('/^#!/')) {
this.router.navigate(
this.url.replace('#!','')
);
}
}
);
}
}
Другой подход, более сложный, на мой взгляд, заключается в использовании пользовательских "matcher". Больше информации здесь:
Вы можете использоватьcanActivate
Guard для перенаправления на URL-адреса без хэша, когда это необходимо:
export const hashRedirectGuard = () =>
((_route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
const router = inject(Router);
const url = state.url;
const newUrl = '/' + trimStart(url, '/#');
return url === newUrl || router.parseUrl(newUrl);
}) satisfies CanActivateFn;
// app-routing.module.ts
const APP_ROUTES: Routes = [
{
path: '',
canActivateChild: [hashRedirectGuard()], // Wrap all routes, see: https://stackoverflow.com/a/43487962/12292636
children: [...],
}
];