Перенаправить все 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". Больше информации здесь:

https://github.com/angular/angular/issues/12442

Вы можете использоватьcanActivateGuard для перенаправления на 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: [...],
  }
];
Другие вопросы по тегам