移动< ng-template>之间的2 ViewContainerRefs之间偶尔会失败 [英] Moving an <ng-template> between 2 ViewContainerRefs occasionally fails

查看:79
本文介绍了移动< ng-template>之间的2 ViewContainerRefs之间偶尔会失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my stackblitz example, I've put a <router-outlet> inside of a ng-template tag so that I can move it between the mobile and desktop parts of the DOM when the window resizes. Eventually something goes wrong and this stops working correctly.

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

To observe the issue open the link below and resize the internal browser window. You should see the text switch between "Desktop" when window.innerWidth > 600px and "Mobile" otherwise. Keep resizing and eventually something goes wrong.

如何解决此问题?

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

推荐答案

首先,您在 switch 语句中省略了 break ,该语句在到达手机壳.因此,如果将 console.log 放在每个方法(loadMobileContent/loadDesktopContent)中,则从移动版本切换到桌面版本后,您会看到每个方法都被称为:

First you have omitted break in in switch statement, which is doesn't stop after reaching 'mobile' case. So if you put console.log in each method(loadMobileContent/loadDesktopContent), you will see after switching from mobile to desktop version each method is called:

  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演示

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

Here is another solution with declarative approach with using ngIf else feature:

<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演示

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

Hey thanks for the effort. Problem with both solutions is that it will reinitialize the component rendered through the . I need to keep the component state as I switch viewports. that's why I'm trying to detach it, not clear it.

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

Ok, then you can detach ViewRef from outlet and insert to another:

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

这将保存组件状态

更新了StackBlitz

这篇关于移动&lt; ng-template&gt;之间的2 ViewContainerRefs之间偶尔会失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆