Различные структуры Layout / html для разных страниц в angular 8 Не работает - PullRequest
0 голосов
/ 11 марта 2020

Я пытался создать публичные c маршруты и безопасные маршруты, каждый с различными структурами html (безопасные маршруты будут выглядеть и выглядеть как панель, в то время как публичные c маршруты имеют более маркетинговую структуру типа), но маршрутизация не работает. У меня такое ощущение, что у меня слишком много <router-outlets>, но я не уверен на 100%.

Мой AppRoutingModule выглядит так:

    const PUBLIC_ROUTES: Routes = [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      { path: 'register', component: RegisterComponent },
      { path: 'login', component: LoginComponent },
      { path: 'request-demo', component: RequestDemoComponent },
      { path: '**', redirectTo: '' }
    ];

    const SECURE_ROUTES: Routes = [
      { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
      { path: 'dashboard', component: DashboardComponent, canActivate: [ LoggedInGuard ] },
      { path: 'u',
        canActivate: [ LoggedInGuard ],
        children: [
          {
            path: ':id',
            component: UserDetailComponent,
            resolve: { user: UserDetailResolver },
            pathMatch: 'full',
          }
        ]
      }
    ];

    const routes: Routes = [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      { path: '', component: PublicLayoutComponent, children: PUBLIC_ROUTES },
      { path: '', component: SecureLayoutComponent, children: SECURE_ROUTES }
    ];

    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    })
    export class AppRoutingModule { }

app.component. html просто <router-outlet></router-outlet>

publi c -layout.component. html is:

    <app-header></app-header>
    <router-outlet></router-outlet>

и secure-layout.component. html is:

    <app-header></app-header>
    <router-outlet></router-outlet>

Мой сервис входа в систему должен перевести вас с publi c -layout на безопасную раскладку через этот маршрутизатор (используя Router) при успешном входе в систему.

    this.router.navigate(["/dashboard"]);

Но при входе это не похоже чтобы работать, пока я все еще на «/», а не на приборной панели и в консоли, проверяя элементы, <app-public-layout> - это то, что отображается.

enter image description here

Обновлено с помощью функции входа в систему login.component.ts:

    login() {
        if (this.authService.login(this.loginModel)) {
          this.loginModel.email = "";
          this.loginModel.password = "";
          console.log(
            "Welcome back " + this.authService.currentUser.firstName
          );
          this.router.navigate(["/dashboard"]);
        } else {
          console.log(
            "Email and/or password is incorrect. Please try again."
          );
          this.loginModel = {
            email: "",
            password: ""
          };
        }
      }

login function in auth service (using local user array for dev):

    login(userEmail: IUserLogin): boolean {
        const userExists = this.users.USERS.find(x => x.email === userEmail.email);
        if (userExists) {
          this.currentUser = userExists;
          localStorage.setItem('user', JSON.stringify(userExists));
          return true;
        } else {
          return false;
        }
      }

охранник вошел в систему:

    @Injectable()
    export class LoggedInGuard implements CanActivate {

        constructor(protected router: Router, protected auth: AuthService ) {}

         canActivate() {
            if (localStorage.getItem('access_token')) {
                return true;
            }
            // not logged in so redirect to login page
            this.router.navigate(['/']);
            return false;
        }
    }

Ответы [ 2 ]

1 голос
/ 11 марта 2020

Ваша проблема в том, как сконфигурирована ваша маршрутизация.

Сведение к проблемным маршрутам оставляет следующую конфигурацию:

const PUBLIC_ROUTES: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'login', component: LoginComponent },
  { path: '**', redirectTo: '' }
];

const SECURE_ROUTES: Routes = [
  { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
  { path: 'dashboard', component: DashboardComponent, canActivate: [ LoggedInGuard ] }
];

const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '', component: PublicLayoutComponent, children: PUBLIC_ROUTES },
  { path: '', component: SecureLayoutComponent, children: SECURE_ROUTES }
];

Когда URL-адрес /, в настоящее время 3 маршрута верхнего уровня, которые маршрутизатор будет пытаться сопоставить.

Следует помнить, что порядок, в котором объявлены маршруты, важен. Маршрутизатор проверит их по порядку.

  1. { path: '', redirectTo: 'home', pathMatch: 'full' }

Одной из проблем в вашем примере является то, что маршрут 'home' не существует.

На данный момент /home не существует, поэтому маршрутизатор откатится на следующий маршрут ...

{ path: '', component: PublicLayoutComponent, children: PUBLIC_ROUTES }

Маршрутизатор будет сопоставляться с первым дочерним элементом, где он найдет еще один redirectTo: 'home'. Затем он вернется к пути '**', который перенаправит на ''. Это сейчас циклический путь. Я подозреваю, что маршрутизатор распознает это и остается на URL /. Он будет отображать PublicLayoutComponent без чего-либо для вставки <router-outlet>.

{ path: '', component: SecureLayoutComponent, children: SECURE_ROUTES }

Маршрутизатор даже не пытался сопоставить этот путь.

Исправление

'**' следует переместить из дочерних маршрутов в маршруты верхнего уровня.

Маршруты верхнего уровня должны быть объявлены в порядке от наиболее специфичных c к наиболее общим.

The LoggedInGuard следует переместить на маршрут верхнего уровня, чтобы сохранить повторное выделение его на каждом дочернем маршруте.

Также необходимо убедиться, что вы добавили 'home' маршрут.

const PUBLIC_ROUTES: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'login', component: LoginComponent }
];

const SECURE_ROUTES: Routes = [
  { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
  { path: 'dashboard', component: DashboardComponent }
];

const routes: Routes = [
  { path: '', component: PublicLayoutComponent, children: PUBLIC_ROUTES },
  { path: '', component: SecureLayoutComponent, children: SECURE_ROUTES, canActivate: [ LoggedInGuard ] },
  { path: '**', redirectTo: '' }
];

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

Отказ от ответственности: Я не прошел исходный код маршрутизатора. Поэтому я не могу утверждать, что точно знаю, как он решает круговые маршруты. Мой ответ основан на моих наблюдениях в этом сценарии.

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

Вам не нужно указывать <router-outlet></router-outlet> в обоих компонентах. Удалите тег маршрутизатора из обоих компонентов и поместите <router-outlet></router-outlet> в родительский компонент, например app.component.ts , и используйте publi c route маршрута по умолчанию, если он не вошел в систему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...