Router-outlet 在 Routerlink 导航后没有更新

Router-outlet is not updating after Routerlink navigation

我正在创建一个带有导航菜单的简单 Angular 应用程序。每个菜单项都有一个 Routerlink 用于在页面之间导航。这是页面:

相关代码:

app.module.ts

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    RouterModule.forRoot(
      [
        {
          path: "",
          redirectTo: "home",
          pathMatch: "full"
        },
        {
          path: "home",
          component: HomeComponent
        },
        {
          path: "customer",
          component: CustomerComponent,
          children: [
            {
              path: "",
              redirectTo: "info",
              pathMatch: "full"
            },
            {
              path: "info",
              component: CustomerInfoComponent,
            },
            {
              path: "details",
              component: CustomerDetailsComponent,
              children: [
                {
                  path: "",
                  redirectTo: "b0",
                  pathMatch: "full"
                },
                {
                  path: "b0",
                  component: CustomerDetailsBlock0Component
                },
                {
                  path: "b1",
                  component: CustomerDetailsBlock1Component
                },
              ]
            }
          ]
        }
      ],
      {useHash: true}
    )
    ],
  declarations: [ AppComponent, CustomerComponent, MenuComponent, HomeComponent, CustomerInfoComponent, CustomerDetailsComponent, CustomerDetailsBlock0Component, CustomerDetailsBlock1Component ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

客户-component.html

<p>This is customer #{{id}}</p>
<app-menu>
  <router-outlet></router-outlet>
</app-menu>

客户详情-component.html

<p>This is customer details</p>
<router-outlet></router-outlet>

客户详细信息块0-component.html

<p>details block0</p>

客户详细信息块 1-component.html

<p>details block1</p>

菜单-component.html

<div>
  <ul>
    <li>
      <a routerLink="">Home</a>
    </li>
    <li>
      <a routerLink="../customer">Customer</a>
      <ul>
        <li>
          <a routerLink="../customer/info">Info</a>
        </li>
        <li>
          <a routerLink="../customer/details">Details</a>
          <ul>
            <li>
              <a routerLink="../customer/details/b0">Block #0</a>
            </li>
            <li>
              <a routerLink="../customer/details/b1">Block #1</a>
            </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
  <p>------------- Content inside menu router-outlet -------------</p>
  <router-outlet></router-outlet>
  <p>--------------------------------------------------------------------</p>
</div>

导航工作正常:当我单击 link 时,激活的路线发生了变化,router-outlet 被更新并显示了预期的组件。

当路由为#/customer/details/b1时刷新页面(或者直接点击,没有点击父菜单项),问题就来了:组件是好的,但是我的菜单被打破。如果我点击 link 去 #/customer/details/b0 路线改变了但是路由器插座没有更新,b1 组件仍然显示并且 b0 没有. 当我单击 URL 不是以 "customer/details" 开头的另一个菜单项时,此问题已修复,例如,如果我单击 "Info",则问题消失。

我想这是组件 customer-details 是同一个实例的问题,因此 Angular 重用它。但是为什么子组件没有改变?

我设法 "fix" 通过在每次调用路由器 shouldReuseRoute 函数时返回 false 来实现此行为:

// menu-component.ts
constructor(private router: Router) {
    this.router.routeReuseStrategy.shouldReuseRoute = () => false;
}

但我不想每次都 destroy/create 我所有的组件。有什么解决办法吗?

这是 Stackblitz demo。要重现错误:

  1. 点击link"Block #1"
  2. 刷新 Stackblitz 输出 window
  3. 点击"Block #0" 或"Details" : 路由已更改但消息仍然是"details block1"
  4. 点击"Info"
  5. 重复步骤 1。 -> 现在问题已解决。

编辑: 我仍然遇到 Angular v6.1.3 的问题(我更新了 Stackblitz demo)。我尝试了@mast3rd3mon 提供的所有解决方案,但似乎无法解决问题。

看了你做的demo,需要去掉router链接的..部分。 ../customer 变为 /customer../customer/info 变为 /customer/info

它可能只是演示,但请确保 app.component.html 文件看起来像 <router-outlet></router-outlet> 而不是 <router-outlet>,因为标签需要有一个结束标签。

问题来自 MenuComponent。您必须插入 <ng-content></ng-content> 而不是 <router-outlet></router-outlet>,因为 <router-outler></router-outlet> 后面的组件在调用 MenuComponent 的组件中初始化(本例中为 CustomerComponent)。

所以menu.component.html中的代码应该是:

<p>------------- Content inside menu router-outlet -------------</p>
<ng-content></ng-content>
<p>--------------------------------------------------------------------</p>

使用路由参数':blockId'[​​=14=]将CustomerDetailsBlock0ComponentCustomerDetailsBlock1Component合并到CustomerDetailsBlockComponent

CustomerDetailsBlockComponent{
   
  blockId: number

  constructor(private router Router){
        this.router.events.subscribe(event=>{
            if (event instanceof ActivationEnd && event.snapshot) {
                let blockId = +event.snapshot.paramMap.get('blockId')
                if (blockId) {
                    this.blockId = blockId
                    //update other angular bindings
                }
            }
        })
  }

}