移动< ng-template>之间的2 ViewContainerRefs之间偶尔会失败 [英] Moving an <ng-template> between 2 ViewContainerRefs occasionally fails
问题描述
在我的闪电战示例中,我将< 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);
}
这是使用 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>
嘿,谢谢您的努力.两种解决方案的问题都在于重新初始化通过渲染的组件.一世切换视口时需要保持组件状态.这就是为什么我试图分离它,而不是清除它.
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);
}
这将保存组件状态
这篇关于移动< ng-template>之间的2 ViewContainerRefs之间偶尔会失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!