在我的stackblitz示例中,我将<router-outlet>
放在了ng-template
标签内,以便在调整窗口大小时可以在DOM的移动部分和桌面部分之间移动它。最终出现问题,这将无法正常工作。
要观察该问题,请打开下面的链接,并调整内部浏览器窗口的大小。当window.innerWidth > 600px
和“移动”之间,您应该看到文本在“桌面”之间切换。继续调整大小,最终出问题了。
如何解决此问题?
https://stackblitz.com/edit/angular-oavajy?file=app%2Fapp.component.html
答案 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);
}
这里是使用 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>
嘿,谢谢您的努力。两种解决方案的问题都在于 重新初始化通过渲染的组件。一世 切换视口时需要保持组件状态。这就是为什么我 试图分离它,而不是清除它。
好,那么您可以ViewRef
,然后插入到另一个:
moveRouterOutlet(fromOutlet: ViewContainerRef, toOutlet: ViewContainerRef): void {
let detached = fromOutlet.detach();
toOutlet.insert(detached);
}
这将保存组件状态