Routerlink导航后,路由器插座未更新

时间:2018-08-01 08:21:50

标签: angular angular-routing angular6 router-outlet

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

  • 首页(#/home
  • 客户/信息(#/customer/info
  • 客户/详细信息(#/customer/details
  • 客户/详细信息/ b0(#/customer/details/b0
  • 客户/详细信息/ b1(#/customer/details/b1

相关代码:

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 { }

customer-component.html

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

customer-details-component.html

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

customer-details-block0-component.html

<p>details block0</p>

customer-details-block1-component.html

<p>details block1</p>

menu-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>

导航正常:当我单击链接时,激活的路线已更改,router-outlet已更新并显示了预期的组件。

当路由为#/customer/details/b1时刷新页面时会出现问题(或者如果我直接单击它而不单击父菜单项):组件是好的组件,但是我的菜单坏了。如果我单击链接转到#/customer/details/b0,则路由已更改,但路由器出口未更新,则b1组件仍显示,而b0未显示。 当我单击URL不以“ customer / details”开头的另一个菜单项时,此问题已得到解决。例如,如果单击“ Info”,则问题就消失了。

Angular_router_bug Angular_router_bug_2

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

每次调用路由器shouldReuseRoute函数时,我都会通过返回false来设法解决此问题:

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

但是我不想每次都破坏/创建我所有的组件。有什么解决办法吗?

这里是Stackblitz demo。重现该错误:

  1. 点击链接“第1块”
  2. 刷新Stackblitz输出窗口
  3. 单击“第0块”或“详细信息”:路由已更改,但消息仍为“详细信息block1”
  4. 点击“信息”
  5. 重复步骤1。->现在,问题已解决。

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

3 个答案:

答案 0 :(得分:1)

看完您的演示后,您需要删除路由器链接的..部分。 ../customer变成/customer../customer/info变成/customer/info等。

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

答案 1 :(得分:1)

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

因此menu.component.html中的代码应为:

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

答案 2 :(得分:0)

使用路由参数':blockId'将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
                }
            }
        })
  }

}