Можно ли деактивировать два одинаковых пути в маршрутизации Angular (таким образом, один активен только одновременно)? - PullRequest
0 голосов
/ 10 марта 2020

Можно ли деактивировать 2 одинаковых Пути с помощью Стражей, которые перенаправляют только в Angular 9? Я пробовал это, но первый все еще активен, когда LogoutGuard возвращает false:

  { path: '', redirectTo: 'login', pathMatch: 'full', canActivate: [LogoutGuard] },
  { path: '', redirectTo: 'home', pathMatch: 'full', canActivate: [LoginGuard] },

В этом примере LogoutRouter возвращает false и LoginRouter true

Так что происходит следующим образом :

Router Event: NavigationStart platform-browser.js:88
NavigationStart(id: 1, url: '/') platform-browser.js:79
Object { id: 1, url: "/", navigationTrigger: "imperative", restoredState: null }
platform-browser.js:79
Angular is running in the development mode. Call enableProdMode() to enable the production mode. core.js:40465
Router Event: RoutesRecognized platform-browser.js:88
RoutesRecognized(id: 1, url: '/', urlAfterRedirects: '/login', state: Route(url:'', path:'') { Route(url:'login', path:'login') { Route(url:'', path:'') }  } ) platform-browser.js:79
Object { id: 1, url: "/", urlAfterRedirects: "/login", state: {…} }
platform-browser.js:79
Router Event: GuardsCheckStart platform-browser.js:88
GuardsCheckStart(id: 1, url: '/', urlAfterRedirects: '/login', state: Route(url:'', path:'') { Route(url:'login', path:'login') { Route(url:'', path:'') }  } ) platform-browser.js:79
Object { id: 1, url: "/", urlAfterRedirects: "/login", state: {…} }
platform-browser.js:79
Router Event: ChildActivationStart platform-browser.js:88
ChildActivationStart(path: '') platform-browser.js:79
Object { snapshot: {…} }
platform-browser.js:79
Router Event: ActivationStart platform-browser.js:88
ActivationStart(path: 'login') platform-browser.js:79
Object { snapshot: {…} }
platform-browser.js:79
Router Event: GuardsCheckEnd platform-browser.js:88
GuardsCheckEnd(id: 1, url: '/', urlAfterRedirects: '/login', state: Route(url:'', path:'') { Route(url:'login', path:'login') { Route(url:'', path:'') }  } , shouldActivate: false) platform-browser.js:79
Object { id: 1, url: "/", urlAfterRedirects: "/login", state: {…}, shouldActivate: false }
platform-browser.js:79
Router Event: NavigationCancel platform-browser.js:88
NavigationCancel(id: 1, url: '/') platform-browser.js:79
Object { id: 1, url: "/", reason: "" }
platform-browser.js:79

1 Ответ

0 голосов
/ 10 марта 2020

Ваша проблема

  • Вы всегда хотите перенаправить с URL /
  • Если пользователь вошел в систему, / следует перенаправить на /home
  • Если пользователь вышел из системы, / должен перенаправить на /login

Ваша реализация

Вы настроили два маршрута с одинаковым путем. Каждый маршрут имеет различное свойство redirectTo и охрану canActivate. Вы ожидаете, что защита будет проверена, и что бы вы ни возвращали true, она затем сообщит маршрутизатору о необходимости перенаправить на соответствующий redirectTo путь.

Это зависит от Angular проверки маршрутизатором определенных c условий в определенный порядок, который явно не происходит.

Мое решение

Добавьте обоих охранников к одному маршруту.

{ path: '', component: AppComponent, canActivate: [LoginGuard, LogoutGuard] },

Вместо возврата по прямой true или false, охранник вернет либо true, либо URL-адрес для перехода.

login.guard.ts

@Injectable({
  providedIn: 'root'
})
export class LoginGuard implements CanActivate {

  constructor(private router: Router) {}

  canActivate(): boolean | UrlTree {  
    const loggedIn = true; // TODO: implement
    if (loggedIn) {
      return true;
    }

    return this.router.parseUrl('login');
  }
}

logout.guard.ts

@Injectable({
  providedIn: 'root'
})
export class LogoutGuard implements CanActivate {

  constructor(private router: Router) {}

  canActivate(): boolean | UrlTree {    
    const loggedIn = true; // TODO: implement
    if (!loggedIn) {
      return true;
    }

    return this.router.parseUrl('home');
  }
}

Естественным шагом отсюда является создание базовой защиты, которая вводится с аутентифицированным состоянием, которое она должна пропустить, и с URL-адресом для перенаправления.

DEMO: https://stackblitz.com/edit/angular-jpzgww

...