Перемещение <ng-template> между 2 ViewContainerRefs иногда не удается
В моем примере Stabblitz я поставил <router-outlet>
внутри ng-template
пометить, чтобы я мог перемещать его между мобильной и настольной частями DOM при изменении размера окна. В конце концов, что-то идет не так, и это перестает работать правильно.
Чтобы увидеть проблему, откройте ссылку ниже и измените размер окна внутреннего браузера. Вы должны увидеть текстовый переключатель между "Рабочим столом", когда window.innerWidth > 600px
и "Мобильный" в противном случае. Продолжайте изменять размер, и в конце концов что-то пойдет не так.
Что можно сделать, чтобы исправить эту проблему?
https://stackblitz.com/edit/angular-oavajy?file=app%2Fapp.component.html
2 ответа
Сначала вы пропустили break
in в операторе switch, который не останавливается после достижения "мобильного" случая. Поэтому, если вы поместите console.log в каждый метод (loadMobileContent/loadDesktopContent), вы увидите, что после переключения с мобильной версии на настольную версию каждый метод вызывается:
switch(newDevice){
case 'mobile': this.loadMobileContent();
case 'desktop': this.loadDesktopContent();
}
Fix:
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);
}
Это сохранит состояние компонента
Я не знаю, какая проблема была там, ожидайте текст
что-то работает
не вел себя должным образом.
я использовал ng-container
вместо ng-template
и это сработало правильно.
Шаблон ng используется для структурных директив, таких как ng-if, ng-for и ng-switch. Если вы используете его без структурной директивы, ничего не происходит и не рендерится.
ng-container используется, когда у вас нет подходящей оболочки или родительского контейнера.
надеюсь это поможет.