在两个ViewContainerRefs之间偶尔移动<ng-template>会失败

时间:2018-06-21 04:48:52

标签: angular

在我的stackblitz示例中,我将<router-outlet>放在了ng-template标签内,以便在调整窗口大小时可以在DOM的移动部分和桌面部分之间移动它。最终出现问题,这将无法正常工作。

要观察该问题,请打开下面的链接,并调整内部浏览器窗口的大小。当window.innerWidth > 600px和“移动”之间,您应该看到文本在“桌面”之间切换。继续调整大小,最终出问题了。

如何解决此问题?

https://stackblitz.com/edit/angular-oavajy?file=app%2Fapp.component.html

2 个答案:

答案 0 :(得分:1)

我不知道该文本是什么问题

  

一些有用的东西

行为异常。

我使用了ng-container而不是ng-template,它可以正常工作。

ng-template用于ng-if,ng-for和ng-switch等结构指令。如果不带结构性指令使用它,则什么也不会发生并呈现。

ng-container用于没有合适的包装器或父容器的情况。

希望这会有所帮助。

答案 1 :(得分:1)

首先,您在 switch 语句中省略了break,但在遇到“移动”情况后并没有停止。因此,如果将 console.log 放在每个方法(loadMobileContent / loadDesktopContent)中,从移动版本切换到桌面版本后,您会看到每个方法都被称为:

  switch(newDevice){
      case 'mobile': this.loadMobileContent();
      case 'desktop': this.loadDesktopContent();
    } 

修复:

 switch (newDevice) {
      case 'mobile':
        this.loadMobileContent();
        break;
      case 'desktop':
        this.loadDesktopContent();
        break;
    }

还将moveRouterOutlet()方法更改为:

  moveRouterOutlet(fromOutlet: ViewContainerRef, toOutlet: ViewContainerRef): void {
    fromOutlet.clear();
    toOutlet.createEmbeddedView(this.tpl);
  }

StackBlitzh Demo

这里是使用 ngIf else 功能的另一种声明式解决方案:

<div>
    <h1 *ngIf="device !== 'mobile' else tpl">Desktop</h1>
    <!-- <div #desktopOutlet></div> -->
</div>

<div>
    <h1 *ngIf="device !== 'desktop' else tpl">Mobile</h1>
    <!-- <div #mobileOutlet></div> -->
</div>

<ng-template #tpl>
    <router-outlet></router-outlet>
</ng-template>

StackBlitz Demo

  

嘿,谢谢您的努力。两种解决方案的问题都在于   重新初始化通过渲染的组件。一世   切换视口时需要保持组件状态。这就是为什么我   试图分离它,而不是清除它。

好,那么您可以分离 ViewRef,然后插入到另一个:

  moveRouterOutlet(fromOutlet: ViewContainerRef, toOutlet: ViewContainerRef): void {
    let detached = fromOutlet.detach();
    toOutlet.insert(detached);
  }

这将保存组件状态

Updated StackBlitz