路由、AuthGuard 和加载子模块

时间:2021-05-25 10:33:15

标签: routes navbar loading angular12

我在这里遇到了一些问题。 我有一个带有 canActivate 的登录页面(当应用程序很简单时它工作得很好)。 我有一个加载了 loadChildren 的管理模块。 在这个模块中,我有一个导航栏和一个侧边栏。

  1. 当应用程序第一次启动时,为什么我的路由没有让我登录?如果我注销并手动导航到仪表板,它将重定向到登录。但是当应用首次打开时,它会进入仪表板。

  2. 当我登录时,导航栏和侧边栏的内容是空的。直到我点击某处的按钮,然后它们突然加载。 (如果当侧边栏最终加载时,我点击侧边栏上的菜单项 - 内容将再次消失,直到我点击某处),情况也是如此。

sidebar.component.html

<div class="sidebar-wrapper" style="background-color:#19203a;">
  <div class="logo column">
    <a href="" class="simple-text">
      <div class="logo-image-small">
        <img src="assets/img/logoname.png">
      </div>
    </a>
  </div>
    <ul class="nav">
        <li *ngFor="let menuItem of menuItems" routerLinkActive="active" class="{{menuItem.class}}">
            <a [routerLink]="[menuItem.path]">
                <i class="nc-icon {{menuItem.icon}}"></i>
                <p style="text-transform:none;">{{menuItem.title}}</p>
            </a>
        </li>
    </ul>
</div>

sidebar.component.ts

import { Component, OnInit } from '@angular/core';


export interface RouteInfo {
    path: string;
    title: string;
    icon: string;
    class: string;
}

export const ROUTES: RouteInfo[] = [
    { path: '/overview', title: 'Overview', icon: 'nc-chart-pie-36', class: '' },
    { path: '/billing', title: 'Billing', icon: 'nc-bulb-63', class: '' },
    { path: '/settings', title: 'Settings', icon: 'nc-settings-gear-65', class: '' },
    { path: '/support', title: 'Support', icon: 'nc-bookmark-2', class: '' },

];

@Component({
    moduleId: module.id,
    selector: 'sidebar-cmp',
    templateUrl: 'sidebar.component.html',
})


export class SidebarComponent implements OnInit {

    public menuItems: any[];

    ngOnInit() {
        this.menuItems = ROUTES.filter(menuItem => menuItem);
    }

}

navbar.component.html

<nav class="navbar navbar-expand-lg navbar-absolute fixed-top navbar-transparent">
  <div class="container-fluid">
    <div class="navbar-wrapper">
      <div  class="column">
      <a class="navbar-brand" href="javascript:void(0)">{{getTitle()}}</a>
      <!-- put in 2 sub headings under here - one 'highlighted' as selected -->
      <div class="row">
        <div style="padding-left: 17px;"><p>subheading</p></div><div style="padding-left: 20px;"><p>subheading</p></div>
      </div>
    </div>
    </div>
    
      <form>
        <div class="input-group no-border">
          <input type="text" value="" class="form-control" placeholder="">
          <div class="input-group-append">
            <div class="input-group-text">
              <i class="nc-icon nc-zoom-split"></i>
            </div>
          </div>
        </div>
      </form>
      <ul class="navbar-nav">
        <li class="nav-item btn-rotate" style="cursor: pointer;">
          <a class="nav-link">
            <i class="nc-icon nc-bell-55"></i>
          </a>
        </li>
        <li class="nav-item" ngbDropdown placement="bottom-left">
          <div style="cursor: pointer;">
            <a class="nav-link btn-rotate"  ngbDropdownToggle id="navbarDropdownMenuLink">
              <p style="text-transform: none; padding-right: 4px;" >Someone
              </p>
              <i class="nc-icon nc-circle-10" ></i>
            </a>
            <div ngbDropdownMenu aria-labelledby="navbarDropdownMenuLink" class="dropdown-menu dropdown-menu-right">
              <a ngbDropdownItem href="javascript:void(0)" (click)="logout()">Log Out</a>
            </div>
          </div>
        </li>
      </ul>
  </div>
</nav>

navbar.component.ts

@Component({
  moduleId: module.id,
  selector: 'navbar-cmp',
  templateUrl: 'navbar.component.html'
})

export class NavbarComponent implements OnInit {
  private listTitles: any[];
  location: Location;

  constructor(
    private authenticationService: AuthenticationService, location: Location, private renderer: Renderer2, private element: ElementRef, private router: Router) {
    this.location = location;
  }

  ngOnInit() {
    this.listTitles = ROUTES.filter(listTitle => listTitle);
  }

  getTitle() {
    var titlee = this.location.prepareExternalUrl(this.location.path());
    if (titlee.charAt(0) === '#') {
      titlee = titlee.slice(1);
    }
    for (var item = 0; item < this.listTitles.length; item++) {
      if (this.listTitles[item].path === titlee) {
        return this.listTitles[item].title;
      }
    }
    return 'Overview';
  }

  logout() {
    this.authenticationService.logout();
    this.router.navigate(['/login']);
  }

}

admin-layout.component.html

<div class="wrapper">
    <div class="sidebar" data-color="#dde2ff" data-active-color="#dde2ff">
        <sidebar-cmp></sidebar-cmp>
    </div>
    <div class="main-panel">
        <navbar-cmp></navbar-cmp>
        <div class="content">
            <router-outlet></router-outlet>
        </div>
        <footer-cmp></footer-cmp>
    </div>
</div>

app.routing.ts

export const AppRoutes: Routes = [
  {
    path: '',
    redirectTo: 'dashboard',
    pathMatch: 'full',
  },
  {
    path: '',
    component: AdminLayoutComponent, //screens with sidebar
    canActivate: [AuthGuard], //need this to trigger login if not authenticated
    children: [
      {
        path: '',
        loadChildren: () => import('./layouts/admin-layout/admin-layout.module').then(m => m.AdminLayoutModule)
      }
    ]
  },
  { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
{ path: 'login', component: LoginComponent }

app.module.ts

@NgModule({
  declarations: [
    AppComponent,
    AdminLayoutComponent,
    LoginComponent,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,
    appRoutingModule,
    FormsModule,
    ReactiveFormsModule,
    NgbModule,
    SidebarModule,
    NavbarModule,
    ToastrModule.forRoot(),
    FooterModule,
    FixedPluginModule
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
    { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },

    fakeBackendProvider // provider used to create fake backend
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

admin-layout.routing.ts

export const AdminLayoutRoutes: Routes = [
    { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard]  },
    { path: 'details', component: DetailsComponent , canActivate: [AuthGuard] },
];
export const routing = RouterModule.forChild(AdminLayoutRoutes);

admin-layout.module.ts

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    routing,
    SidebarModule,
    NavbarModule,
    NgbModule
  ],
  declarations: [
    DashboardComponent,
  ]
})

export class AdminLayoutModule {}

1 个答案:

答案 0 :(得分:0)

  1. 因为您将用户重定向到 AppModule 中的 functools.reduce,而 AppModule 中未声明 from functools import reduce reduce(np.add.outer, df.values.T).ravel()

  2. 由于 1 和您的架构存在一些问题,让我列出一些:

首先您不需要组件来定义子路由的路由。在你的 appRoutes 中,写这个

/dashboard

这是一个无组件的路由,它允许你保护所有的孩子,所以你不需要在 AdminLayout 中重复 canActivate。

第二 Admin Routes 那么必须是:

DashboardComponent

最后 export const AppRoutes: Routes = [ { path: '', redirectTo: 'dashboard', pathMatch: 'full', }, { path: 'dashboard', loadChildren: () => import('./layouts/admin-layout/admin-layout.module') .then(m => m.AdminLayoutModule), canActivate: [AuthGuard] }, { path: 'login', component: LoginComponent }]; 在 AdminLayoutModule 中声明,因此您不能在 export const AdminLayoutRoutes: Routes = [ { path: '', children:[ { path: '', component: DashboardComponent}, { path: 'details', component: DetailsComponent}, ]} ]; export const routing = RouterModule.forChild(AdminLayoutRoutes); DashboardComponent 中使用它,只能在声明它的 AdminLayoutModule 中使用它。< /p>

注意:如果您不明白我的意思,您可以创建一个 stackblitz project,我会为您编辑。这是我的工作存储库 https://github.com/bellash13/dee-stackoverflow

相关问题