【问题标题】:Angular router links do not work until app is reloaded with browser's refresh button在使用浏览器的刷新按钮重新加载应用程序之前,Angular 路由器链接不起作用
【发布时间】:2019-08-08 10:56:56
【问题描述】:

在我的 Angular(v7) 应用程序中,尽管浏览器地址栏中的 URL 已更改,但单击路由器链接不会加载相关组件。

一旦页面重新加载,点击浏览器的刷新按钮,路由器链接就会开始按预期工作。我已确认 Google Chrome 和 IE 中的行为。

您能否告诉我我做错了什么以及在哪里?我在下面分享了我的代码的相关部分。

应用模块和路由器设置

import {
  RouterModule,
  Routes
} from "@angular/router";
...

const appRoutes: Routes = [{
    path: 'login',
    component: LoginComponent
  },
  {
    path: 'bookings', 
    component: BookingsComponent, 
    canActivate: [AuthGuard]}, 
  {
    path: 'rates', 
    component: RatesComponent, 
    canActivate: [AuthGuard]},
  {
    path: '',
    redirectTo: '/bookings',
    pathMatch: 'full',
    canActivate: [AuthGuard]
  },
  {
    path: '**',
    component: PageNotFoundComponent
  },
];

@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes, {
      enableTracing: false
    }),
    BrowserModule,
    ...
  ]
})
export class AppModule {}

HTML 模板中的路由器链接

<a class="side-nav-link" routerLink="/rates" routerLinkActive="active">Rates</a>
<a class="side-nav-link" routerLink="/bookings" routerLinkActive="active">Bookings</a>

Auth Guard,如果相关

@Injectable({
  providedIn: "root"
})
export class AuthGuard implements CanActivate {

  constructor(private router: Router, private authService:AuthService) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

    if (this.authService.loggedIn) {
      return true;
    }

    this.router.navigate( ['/login'], { queryParams: { returnUrl: state.url }});
    return false;
  }
}

【问题讨论】:

  • 你还没有为ratesbookings定义路由
  • @ashishpal 我的实际代码中有这些路线。我也在问题的代码 sn-p 中添加了相同的内容。
  • 你能把enableTracing设置为true并添加一些日志吗?
  • 不要在同一个组件中使用多个路由器插座..使用路由子方法..它会工作..

标签: angular typescript angular-routing


【解决方案1】:

我遇到了同样的问题。这是由于在一个页面上有两个路由器插座并使用 ngIf 在两者之间切换造成的。这似乎是 Angular 的反模式。

原因

这是我正在做的一个例子:

文件:app.component.html

<!-- Show toolbar and sidenav if logged in -->
<mat-toolbar *ngIf="isLoggedIn()">My App</mat-toolbar>
<mat-sidenav-container *ngIf="isLoggedIn()">
  <mat-sidenav>
    <mat-nav-list>
      <a mat-list-item routerLink="/page1">Page 1</a>
      <a mat-list-item routerLink="/page2">Page 2</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <router-outlet></router-outlet>
  </mat-sidenav-content>
</mat-sidenav-container>

<!-- Hide toolbar and sidenav if NOT logged in -->
<router-outlet *ngIf="isLoggedIn() === false"></router-outlet>

文件:app-routing.module.ts

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'page-1', component: Page1Component, canActivate: [AuthGuard] },
  { path: 'page-2', component: Page2Component, canActivate: [AuthGuard] },
  { path: '**', redirectTo: 'page-1' }
];

我这样做是因为我想要两种布局:一种用于我的主要应用内容(带有工具栏和侧边导航),另一种用于我的登录页面(没有工具栏和侧边导航)。

解决方案

这样做的正确方法是创建两个组件,一个用于我想要的每个布局,然后使用 routers 子属性。 Link to docs。例如:

文件:app.component.html

<router-outlet></router-outlet>

文件:layouts/main-layout.component.html

<mat-toolbar>My App</mat-toolbar>
<mat-sidenav-container>
  <mat-sidenav>
    <mat-nav-list>
      <a mat-list-item routerLink="/page1">Page 1</a>
      <a mat-list-item routerLink="/page2">Page 2</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <router-outlet></router-outlet>
  </mat-sidenav-content>
</mat-sidenav-container>

文件:layouts/login-layout.component.html

<router-outlet></router-outlet>

文件:app-routing.module.ts

const routes: Routes = [
  {
    path: 'login', component: LoginLayoutComponent, children: [
      { path: '', component: LoginComponent },
    ]
  },
  {
    path: '', component: MainLayoutComponent, children: [
      { path: 'page-1', component: Page1Component, canActivate: [AuthGuard] },
      { path: 'page-2', component: Page2Component, canActivate: [AuthGuard] },
      { path: '**', redirectTo: 'page-1' }
    ]
  },
];

希望这会有所帮助:)

【讨论】:

  • 这应该是公认的答案。谢谢先生,我遇到了同样的问题,您的解决方案有效。
  • 注意:以防万一任何人在做同样的事情,我正在做实时重新加载并且解决方案在我用ng serve重新编译之前不起作用。
  • @david-maccallum 你能帮我这个stackoverflow.com/questions/65697694/…
【解决方案2】:
const appRoutes: Routes = [{
  path: 'login',
  component: LoginComponent
 },
 {
  path: 'rates',
  component: RatesComponent
 },
 {
  path: 'bookings',
  component: BookingsComponent
 },
 {
  path: '',
  redirectTo: '/bookings',
  pathMatch: 'full',
  canActivate: [AuthGuard]
 },
 {
  path: '**',
  component: PageNotFoundComponent
 },
];

你的路线应该是这样的。

【讨论】:

  • 我的实际代码中实际上有这些路由器。请检查已编辑的问题。
  • 这是发生在本地还是部署构建到服务器?
猜你喜欢
  • 2014-10-06
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
  • 2015-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多