Header 在 Angular 7 路由器上消失

Header disappears on Angular 7 router

我最近从 angular 5 升级到 7。在最近 ng-conf 看了 Deborah Kurata 的 this 演示后,我决定更新我相当糟糕的路由代码。

我决定在应用程序组件之上实现她的 shell 组件来处理路由,然后在需要时 lazy-load 每个功能模块。这是我目前所拥有的:

app.component.html

<router-outlet></router-outlet>

app-routing.module.ts

import { Injectable, NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { AccessGuard }           from './shared/guards/access.guard';
import { LoginComponent }        from './login/login.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

export const appRoutes: Routes = [
  { 
    path: 'login', 
    component: LoginComponent, 
    data: { requiresLogin: false },  
    canActivate: [ AccessGuard ] 
  },
  { path: '**', component: PageNotFoundComponent }
];

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

所以在这里您可以看到我只关心应用程序根目录中的登录和 page-not-found 视图。下面是 shell.module,它应该是其他一切的主要路由器:

shell.component.html

<app-header></app-header>
<router-outlet name="primary"></router-outlet>

shell-routing.module.ts

import { Injectable, NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { Observable }           from 'rxjs';

import { AccessGuard }        from '../shared/guards/access.guard';
import { DashboardComponent } from '../dashboard/dashboard.component';
import { ShellComponent }     from './shell.component';

export const shellRoutes: Routes = [
  { 
    path: '', 
    component: ShellComponent,
    data: { requiresLogin: true },
    canActivate: [ AccessGuard ],
    children: [
      { 
        path: 'dashboard', 
        component: DashboardComponent,
        data: { requiresLogin: true },
        canActivate: [ AccessGuard ] 
      },
      {
        path: 'posts',
        loadChildren: 'app/posts/posts.module#PostsModule'
      },
      {
        path: 'user-profile',
        loadChildren: 'app/user-profile/user-profile.module#UserProfileModule'
      }
    ]
  },
  { 
    path: '',
    redirectTo: '/dashboard', 
    pathMatch: 'full'
  }
];

@NgModule({
  imports: [ RouterModule.forChild(shellRoutes) ],
  exports: [ RouterModule ],
  providers: [ AccessGuard ]
})
export class ShellRoutingModule {}

同样,如您所见,我正在延迟加载 Posts 和 UserProfile 模块。最后是前面提到的模块路由:

posts-routing.module.ts

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

import { AccessGuard }    from '../shared/guards/access.guard';
import { PostsComponent } from './posts.component';
import { PostComponent }  from './post/post.component';

const postsRoutes: Routes = [
  {
    path: '',
    redirectTo: 'add',
    pathMatch: 'full'
  },
  {
    path: 'add',
    component: PostComponent,
    data: { requiresLogin: true },
    canActivate: [ AccessGuard ],
  },
  {
    path: 'comment/:id',
    component: PostComponent,
    data: { requiresLogin: true },
    canActivate: [ AccessGuard ],
  },
  {
    path: 'edit/:id',
    component: PostComponent,
    data: { requiresLogin: true },
    canActivate: [ AccessGuard ],
  } 
];

@NgModule({
  imports: [ RouterModule.forChild(postsRoutes) ],
  exports: [ RouterModule ],
  providers: [ AccessGuard ]
})
export class PostsRoutingModule { }

user-profile-routing.module.ts

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

import { AccessGuard }  from '../shared/guards/access.guard';

import { UserProfileComponent }   from './user-profile.component';
import { FollowersComponent }     from './followers/followers.component';
import { FollowingComponent }     from './following/following.component';
import { MentorsComponent }       from './mentors/mentors.component';
import { CoachesComponent }       from './coaches/coaches.component';
import { NotificationsComponent } from './notifications/notifications.component';
import { AdminMentorComponent }   from './admin-mentor/admin-mentor.component';

const userProfileRoutes: Routes = [ 
  {
    path: 'user-profile',
    data: { requiresLogin: true },
    children: [
      {
        path: ':id',
        data: { requiresLogin: true },
        canActivate: [ AccessGuard ],
        children: [
          {
            path: '',
            component: UserProfileComponent,
          },
          {
            path: 'followers',
            component: FollowersComponent
          },
          {
            path: 'following',
            component: FollowingComponent
          },
          {
            path: 'mentors',
            component: MentorsComponent
          },
          {
            path: 'coaches',
            component: CoachesComponent
          },
          {
            path: 'notifications',
            component: NotificationsComponent
          }
        ]
      }
    ]
  }
];

@NgModule({
  imports: [ RouterModule.forChild(userProfileRoutes) ],
  exports: [ RouterModule ],
  providers: [ AccessGuard ]
})
export class UserProfileRoutingModule { }

问题

为什么根据以上所述,header出现在posts路由中,而没有出现在用户配置文件路由中?


编辑

不幸的是,我无法在 StackBlitz 上模仿这种行为。一切都出现了。我将注释掉我的 header.component 代码并将其替换为其他内容以查看它是否出现。


编辑 2

正如我之前编辑中提到的,我无法正确模拟行为。我能想到的演示我的问题的唯一其他方法是:当我像这样导航到 posts 路线时:

<input placeholder="How are you today?" routerLink="/posts/add">

我可以在 DOM 树中看到目标是正确的 router-outlet(shell.component 中的那个)和 post 组件(app-post) 在其旁边插入:

但是,user-profile 的组件不会这样做。他们进入 app.component 旁边,而不是 shell.component 中的那个。我像这样硬编码到 user-profile 的路由:

<p routerLink="/user-profile/6">Testing testing</p>

进行测试,但得到了相同的消失 header 结果。

这对我来说真的很奇怪。两个组件路由都导入到 shell-routing.module 中,因此应该将它们的组件放在它旁边。

那么有什么好处呢?

此外 - 我说的正确吗,当您尝试通过“/some-path/here”导航时,您使用的是 绝对路径 而不是相对路径,因此它应该工作?嘟嘟

发生这种情况的原因是,当您在 Angular 中延迟加载模块并将路由定义为子路由时,其父路由必须包含 router-outlet 才能添加子路由,否则它会获胜没用。

另一个关键点是,当进行更改时,例如添加延迟加载模块或修改其路由,您需要重新启动您的应用程序并使用 --aot 标志提供服务:

ng serve --aot

查看您的更改是否生效。