0

我这里有几个问题。我有一个带有 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);

管理布局.module.ts

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

export class AdminLayoutModule {}
4

1 回答 1

0
  1. 因为您将用户重定向到/dashboardAppModule 中,而未在 AppModule 中DashboardComponent声明。

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

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

   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 
   }];

这是一个无组件路由,它允许您保护所有子级,因此您无需在 AdminLayout 内重复 canActivate。

第二个管理员路由必须是:

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

Finaly DashboardComponent在 AdminLayoutModule 内部声明,因此您不要在内部AppModule或 in 中使用它AppRoutingModule,只能在声明它的 AdminLayoutModule 内部使用它。

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

于 2021-05-27T18:03:33.190 回答