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
查看您的更改是否生效。
我最近从 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
查看您的更改是否生效。