使用 ContentChildren 获取页面上的所有路由器链接

Using ContentChildren to get all the router links on a page

如果我向我的组件添加内容子项

@ContentChildren(RouterLink, { descendants: true })
links: QueryList<RouterLink>;

并有模板

<a [routerLink]="''">Link 1</a><br>
<a [routerLink]="''">Link 2</a><br>
<a [routerLink]="''">Link 3</a><br>
Number of links: {{links.length}}

链接长度始终为 0。

我也试过指令

@Directive({
  selector: '[appRouterLinkWatch]'
})
export class RouterLinkWatchDirective implements AfterContentInit {
  @ContentChildren(RouterLink, { descendants: true })
  links: QueryList<RouterLink>;

  constructor(@Optional() private link: RouterLink) {}

  ngAfterContentInit() {
    console.log(this.links.length, this.link);
  }
}

link 的内容子项和 link 依赖项均未填充。在我的组件中获取路由器 link 列表我做错了什么?

我一直在查看 routerLinkActive 指令的源代码 https://github.com/angular/angular/blob/master/packages/router/src/directives/router_link_active.ts 我看不出我在做什么不同。

我这里有一个堆栈闪电战 https://stackblitz.com/edit/angular-ivy-bvpyhd?file=src%2Fapp%2Fapp.component.html

看来 RouterLink 指令在内部使用了两种不同的类型。

RouterLinkRouterLinkWithHref

直接在组件中计数routerLink

如果我们想直接在组件中计算 routerLinks,并且希望没有投影链接,那么我们必须使用 @ViewChildren() 而不是 @ContentChildren()

@Component({...})
export class AppComponent implements AfterViewInit {
  @ViewChildren(RouterLink) routeWithoutHref!: QueryList<RouterLink>;
  @ViewChildren(RouterLinkWithHref) routeWithHref!: QueryList<RouterLinkWithHref>;

  ngAfterViewInit() {
    console.log(this.routeWithHref.length); // expect 2
    console.log(this.routeWithoutHref.length); // expect 1
  }
}
<a routerLink>link</a>
<a routerLink="a">link</a>
<div routerLink="b">link</div>

上面的组件为 RouterLinkWithHref 生成长度为 2,为 RouterLink 生成长度为 1,我从中总结它取决于 RouterLink 是否附加到锚点或没有。

指令是否有任何输入似乎没有任何影响。

从指令计算 RouterLink

和以前一样,除了我们现在使用 ContentChildren 而不是 ViewChildren

@Directive({selector: '[countRoutes]'})
export class RouteCountDirective implements AfterContentInit{
  @ContentChildren(RouterLink, {descendants: true}) routerLinks!: QueryList<RouterLink>
  @ContentChildren(RouterLinkWithHref, {descendants: true}) routerLinksWithHref!: QueryList<RouterLinkWithHref>

  ngAfterContentInit() {
    console.log(this.routerLinks.length) // 1
    console.log(this.routerLinksWithHref.length) // 2
  }
}
<div countRoutes>
  <a routerLink>link</a>
  <a routerLink="a">link</a>
  <div routerLink="b">link</div>
</div>

通知

当对 ContentChildren 使用 {descendants: true} 选项时,只有 routerLinks 嵌套在附加了 countRoutes 指令的元素中。

<div countRoutes>
  <a routerLink>Counted</a>
  <a routerLink="a">Counted</a>
  <div routerLink="b">Counted</div>
</div>
<a routerLink="c">Not Counted</a>