角度:在一个组件中两次使用相同的<router-outlet>

时间:2019-03-21 16:11:26

标签: angular

免责声明:这是Changing router-outlet with *ngIf in app.component.html in angular2的副本,该副本的接受答案虽然不能解决我的情况。

这是我的问题:我想在我的主要组件中有两次相同的“路由器出口”。似乎只有第二个“路由器出口”获胜并正确显示内容。建议将路由器出口包装在ng-template中的解决方案对我不起作用。

这是我在代码中的情况:

<div class="mobile-only">
  <div>some special content for mobile version</div>
  <router-outlet></router-outlet>
</div>

<div class="desktop-only">
  <div>some special content for desktop version</div>
  <router-outlet></router-outlet>
</div>

当用户浏览页面时,仅第二个路由器插座得到更新。第一个路由器出口被角度抛弃了。

问题:如何重用路由器插座?

编辑:我试图将路由器插座包装在ng模板中,但是它没有用:https://stackblitz.com/edit/router-outlet-in-template-not-working-example-cpyjbq

这是一个有效的版本:https://stackblitz.com/edit/router-outlet-in-template-working-example

我实际上可以重用路由器出口---但仅以在setTimeout中重新分配模板变量为代价。作为令人讨厌的副作用,重新实例化了这些组件。

4 个答案:

答案 0 :(得分:2)

如果要在同一组件模板中使用多个插座,则需要使用named outlets。但是它们旨在与辅助路径一起使用,而不是与主要路径一起使用...我不知道哪个用例有两个出口,但是如果您要显示与移动设备和台式机不同的内容,则应该考虑使用创建两个不同的应用程序,但这只是一个建议!

因此,如果要使用命名出口,则需要给每个出口起一个名称,如下所示:

<div class="mobile-only">
  <div>some special content for mobile version</div>
  <router-outlet name="mobile-content"></router-outlet>
</div>

<div class="desktop-only">
  <div>some special content for desktop version</div>
  <router-outlet name="desktop-content"></router-outlet>
</div>

然后,您可以将路由重定向到路由文件上的特定出口,如下所示:

{
  path: 'mobile',
  component: MobileContentComponent,
  outlet: 'mobile-content'
},
{
  path: 'desktop',
  component: DesktopContentComponent,
  outlet: 'desktop-content'
}

如果要通过routerLink指令重定向到此路由,则可以从模板重定向,如下所示:

<a [routerLink]="[{ outlets: { mobile-content: ['mobile'] } }]">Mobile Content</a>
<a [routerLink]="[{ outlets: { desktop-content: ['desktop'] } }]">Desktop Content</a>

编辑

我刚刚在StackBlitz上看到了您的代码,问题是您在模板中两次显示了路由器插座模板。您需要根据条件显示一个或另一个。我已经用一个变量修改了您的StackBlitz here,该变量将根据条件显示一个或另一个路由器插座(您可以检查屏幕尺寸或所需的任何尺寸)。

但是查看您的代码我不明白为什么需要两个路由器插座...如果您只想在路由器插座的父div上触发一个类,则可以使用ngClass来使用一个班级或其他根据scren大小。

答案 1 :(得分:0)

我想我通过听路由器事件找到了另一种解决方案:

https://stackblitz.com/edit/router-outlet-twice-with-events

在这次堆叠闪电战中,我实际上同时使用了路由器出口的两个模板。这是有效的解决方法吗?

答案 2 :(得分:0)

试图为此找到解决方法的时候,我最终得到了

HTML

<div id="mobile">
 <router-outlet *ngIf="isMobile"></router-outlet>
</div>
<div id="desktop">
 <router-outlet *ngIf="isDesktop"></router-outlet>
</div>

TS

export class ExampleComponent implements AfterViewInit {

  private initied: boolean
  constructor (
    private cdref: ChangeDetectorRef
  ) { }

  ngAfterViewInit (): void {
    this.initied = true
    this.cdref.detectChanges()
  }

  get isDesktop (): boolean {
    if (!this.initied) { return false }
    return this.checkHidden('router-mobile')
  }

  get isMobile (): boolean {
    if (!this.initied) { return false }
    return this.checkHidden('router-desktop')
  }

  private checkHidden (id: string): boolean {
    return (document.getElementById(id).getAttribute('style') as string).includes('display: none')
  }
}

答案 3 :(得分:0)

我尝试了以下方法,并正在帮助我展示彼此排斥的事物

HTML

<div id="mobile">
 <router-outlet *ngIf="!getIfMobile"></router-outlet>
</div>
<div id="desktop">
 <router-outlet *ngIf="getIfMobile"></router-outlet>
</div>

Component.ts

get getIfMobile() {
    return window.innerWidth < 720;
}