Переключение компонента компоновки на основе Angular 2 Guard

Так что это может быть длинный пост, но я надеюсь, что кто-то может мне помочь:)

Я создаю веб-приложение Angular 2 с "разделенной" компоновкой, то есть я буду использовать отдельный компонент компоновки в зависимости от того, прошел ли я проверку подлинности через средство защиты маршрута.

Когда я вхожу в приложение в первый раз, и у меня нет активного сеанса или файла cookie с сервера, я буду перенаправлен на страницу входа в систему, но только если эта страница защищена средством защиты маршрутизации. Эта страница входа будет переведена в "публичный" вид, который не содержит <header>, <footer> или же <nav> теги в нем.

Цель этого состоит в том, чтобы иметь возможность загружать один макет HTML с <router-outlet></router-outlet> для компонентов вида, которые требуют, чтобы пользователь вошел в систему, и имеют другой <router-outlet></router-outlet> в другом компоненте представления, когда пользователь пытается получить доступ к "частному" маршруту.

Внутри index.html

<html>
<head></head>
<body>
    <!-- Load application -->
    <my-app>
        <div class="vertical-wrapper center-block">
            <div class="vertical-align">
                <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
                <span class="sr-only">Loading Application...</span>
            </div>
        </div>
    </my-app>

    <!-- Scripts -->
    <script src="/dist/app.vendor.js"></script>
    <script src="/dist/app.js"></script>

    <!-- Development Server Reloading -->
    <script src="/webpack-dev-server.js"></script>
</body>
</html>

Файл Routes.ts

// Required Imports.
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';

// Routes values
import { PUBLIC_ROUTES } from  'app/routes/public.routes';
import { PRIVATE_ROUTES } from 'app/routes/private.routes';

// Layouts
import { PublicComponent, PrivateComponent } from 'app/layouts';

// Import Pages
import { NotFoundPage } from 'app/pages';

// Guards
import { LoginGuard } from 'app/services/login.guard';

const routes: Routes = [
    {
        canActivate: [LoginGuard],
        path: '',
        component: PrivateComponent,
        children: PRIVATE_ROUTES
    },
    {
        path: '',
        component: PublicComponent,
        children: PUBLIC_ROUTES
    },

    // Greedy-route sending everything not caught to 404 page.
    { path: '**', component: NotFoundPage }
];

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

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

Файл приватных маршрутов

import { StartPage, ListComponent } from 'app/pages';

export const PRIVATE_ROUTES = [
    {
        path: '',
        component: StartPage
    },
    {
        path: 'start',
        component: StartPage
    },
    {
        path: 'lists',
        component: ListComponent
    }
];

Файл открытых маршрутов

import { LoginPage, LogoutPage } from 'app/pages';

export const PUBLIC_ROUTES = [
    {
        path: 'login',
        component: LoginPage
    },
    {
        path: 'logout',
        component: LogoutPage
    }
];

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

Теперь к финальной части. Внутри моей папки "раскладки" у меня есть оба private.component.html и public.component.html оба содержат <router-outlet></router-outlet>,

Частный компонент HTML

<div id="page-wrapper" [ngClass]="{'toggled': ShowNavigation}">
    <div id="navigation-wrapper">
        <navigation></navigation>
    </div>

    <div id="content-wrapper">
        <header class="col-xs-12 fixed-height-60" style="border-bottom: 2px solid #92A92A">
            <div class="pull-right vertical-wrapper">
                <div class="vertical-align padding-right-x1">
                    <span class="col-sm-12 hidden-xs text-right">{{CurrentUser.userDisplayName}}</span>
                    <span class="col-sm-12 hidden-xs text-right">{{CurrentUser.clientDescription}}</span>
                </div>

                <div class="vertical-align image-wrapper">
                    <div class="col-sm-12 col-xs-9 pull-xs-right">
                        <div class="row">
                            <img class="image" [src]="BrandingLogo" alt="Banding logo" />
                        </div>
                    </div>
                </div>
            </div>
        </header>

        <section class="col-xs-12">
            <router-outlet></router-outlet>
        </section>
    </div> 
</div>

Публичный компонент html

<div class="container-fluid">
    <div class="row">
        <router-outlet></router-outlet>
    </div>
</div>

У меня вопрос, как мне зарегистрировать маршрутных детей, которые должны быть доступны только в том случае, если охрана маршрута это позволяет? Мне нужно иметь возможность переключать макет, потому что только внутри самого приложения вы сможете просматривать <nav> например.

Я знаю, что это не лучший способ сделать это, но именно так мне удалось это решить. Не стесняйтесь вносить вклад во все, что может помочь мне улучшить это.

  • Есть ли хороший способ сделать это?
  • Я на правильном пути, или я полностью потерял это?

Я обеспечу вас охраной, если кому-то из вас это тоже понадобится.

import { Inject, Injectable } from '@angular/core';
import { LoginService } from 'app/services/login.service';

import {
    CanActivate,
    Router,
    RouterStateSnapshot,
    ActivatedRouteSnapshot
} from '@angular/router';

@Injectable()
export class LoginGuard implements CanActivate {
    constructor(
        @Inject(LoginService) private loginService: LoginService,
        @Inject(Router) private router: Router
    ) { }

    canActivate( activatedRoute: ActivatedRouteSnapshot,
                 routerState: RouterStateSnapshot       ): boolean {

        if (this.loginService.User)
            return true;

        this.router.navigate(['/login', { redirect: routerState.url.substr(1) }]);
        return false;
    }
}

Вот обзор моего исходного дерева

Не стесняйтесь спрашивать меня, если я не достаточно ясно.

0 ответов

Другие вопросы по тегам