离子/角形嵌套路由器出口:routerLinks只工作一次

时间:2020-08-14 17:24:30

标签: angular typescript ionic-framework routes angular-routing

我正在尝试使用Angular's routing guide在Angular Ionic v5应用程序中实现嵌套/子路由的简单示例。我使用ionic start创建了一个项目,并选择了blank模板,然后创建了两个组件ChildAComponentChildBComponent。以下是home.page.html中的相关代码段:

<div id="container">
  <strong>Ready to create an app?</strong>
  <p>Start with Ionic <a target="_blank" rel="noopener noreferrer"
      href="https://ionicframework.com/docs/components">UI Components</a></p>
  <div id="stuff">
    <a routerLink="child-a">Child A</a><br>
    <a routerLink="child-b">Child B</a><br>
    <a routerLink="404">404</a>
  </div>
  <div id="thing">
    <router-outlet></router-outlet>
  </div>
</div>

我正在尝试使用a标签来驱动router-outlet中呈现的组件。首次加载页面(URL:/home)时,我可以单击其中一个链接,并在出口中渲染适当的子元素。 发生这种情况时,href标记上的a s(我假设Angular根据routerLink s放置了它们)< em> 所有更改 到导航的URL。

这样,在不重新加载页面的情况下(回到/home),我无法单击另一个组件链接来呈现该组件。

点击链接之前(URL为/home):

href's correct

点击“子级”链接后(URL为/home/childa):

enter image description here

Angular文档似乎没有表明我配置不正确,与heroes example中的路由相比,我在代码中看不到任何明显不同的地方。我在做什么错了?

如果有帮助,这里是我的home-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomePage } from './home.page';
import { ChildAComponent } from './childa/childa.component';
import { ChildBComponent } from './childb/childb.component';

const routes: Routes = [
  {
    path: '',
    component: HomePage,
    children: [
      {
        path: 'child-a',
        component: ChildAComponent,
      },
      {
        path: 'child-b',
        component: ChildBComponent,
      },
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class HomePageRoutingModule {}

GitHub: https://github.com/zrev2220/router-link-bug

1 个答案:

答案 0 :(得分:1)

简短回答

您必须在您的RouterLink指令中添加绝对路径

<a [routerLink]="['/home', 'child-a']">Child A</a><br>
<a [routerLink]="['/home', 'child-b']">Child B</a><br>

详细答案

首先让我们了解RouterLink(特别是RouterLinkWithRef)伪指令的工作方式。它将导航到的路线取决于当前激活的路线(ActivatedRoute)。当您点击带有RouterLinkWithRef指令(例如selector: 'a[routerLink]')的元素时,这就是what happens

/* ... */
this.router.navigateByUrl(this.urlTree, extras);
/* ... */

其中this.urlTree被定义为getter

get urlTree(): UrlTree {
  return this.router.createUrlTree(this.commands, {
    relativeTo: this.route, // !
    queryParams: this.queryParams,
    fragment: this.fragment,
    preserveQueryParams: attrBoolValue(this.preserve),
    queryParamsHandling: this.queryParamsHandling,
    preserveFragment: attrBoolValue(this.preserveFragment),
  });
}

我们看到的是relativeTo: this.route,其中this.routeinjected as ActivatedRoute

这就是问题发生的原因:当当前路由为/home时,在指令中注入的激活路由应不同于/home/child-*中的路由;在这种情况下,是相同的。

因此,当用户首次登陆/home时,在指令中注入的ActivatedRoute将具有特定值,我们将其称为X。但是,当用户转到/home/child-a时,router-outlet之外的视图将保持不变,ActivatedRoute的值也将保持不变。这很重要,因为当处理绝对路径和相对路径路径时(提供给路由器指令的任何不带/的路径),Angular都会遍历当前的UrlTreeUrlTree =以字符串形式提供的路径路径的反序列化版本),并将尝试用新部分替换旧部分。
用户导航到/home/child-a之后,在当前的UrlTree中将无法在指令中查找从当前ActivatedRoute创建的旧零件,因为ActivatedRoute不再对应于 actual 激活的路径,因此它是过时的