Отказ от ответственности: это дубликат Изменение выхода маршрутизатора с помощью * ngIf в app.component.html в angular2, у которого есть принятый ответ, который, однако, не решает мою ситуацию.
Итак, вот моя проблема: я хотел бы иметь один и тот же «маршрутизатор» дважды в моем основном компоненте. Как кажется только второй "роутер-розетка" выигрывает и корректно отображает контент. Предлагаемое решение обернуть выход маршрутизатора в шаблон ng не работает для меня.
Это моя ситуация в коде:
<div class = "mobile-only">
<div>some special content for mobile version</div>
<router-outlet></router-outlet>
</div>
<div class = "desktop-only">
<div>some special content for desktop version</div>
<router-outlet></router-outlet>
</div>
Только второй маршрутизатор-выход обновляется, когда пользователь перемещается по странице. Первый роутер-розетка заброшен угловой.
Вопрос: Как повторно использовать роутер-розетку?
Обновлено: я попытался обернуть выход маршрутизатора в шаблон ng, но это не сработало: https://stackblitz.com/edit/router-outlet-in-template-not-working-example-cpyjbq
А вот рабочая версия: https://stackblitz.com/edit/router-outlet-in-template-working-example
На самом деле я могу повторно использовать маршрутизатор-выход --- но только за счет переназначения переменной шаблона в setTimeout. В качестве неприятного побочного эффекта компоненты воссоздаются.





Если вы хотите использовать несколько торговых точек в одном и том же шаблоне компонента, вам нужно использовать именованные торговые точки. Но они предназначены для работы с вторичными маршрутами, а не с первичными... Я не знаю, в каком случае вы используете два выхода, но если вы собираетесь отображать разный контент с мобильного и рабочего стола, вместо этого вам следует рассмотреть возможность создайте два разных приложения, но это только рекомендация!
Итак, если вы хотите использовать именованные розетки, вам нужно дать каждой розетке имя, например:
<div class = "mobile-only">
<div>some special content for mobile version</div>
<router-outlet name = "mobile-content"></router-outlet>
</div>
<div class = "desktop-only">
<div>some special content for desktop version</div>
<router-outlet name = "desktop-content"></router-outlet>
</div>
Затем вы можете перенаправить свои маршруты к определенному выходу в вашем файле маршрутизации следующим образом:
{
path: 'mobile',
component: MobileContentComponent,
outlet: 'mobile-content'
},
{
path: 'desktop',
component: DesktopContentComponent,
outlet: 'desktop-content'
}
Если вы перенаправляете на эти маршруты через директиву routerLink, вы можете перенаправить из шаблона следующим образом:
<a [routerLink] = "[{ outlets: { mobile-content: ['mobile'] } }]">Mobile Content</a>
<a [routerLink] = "[{ outlets: { desktop-content: ['desktop'] } }]">Desktop Content</a>
РЕДАКТИРОВАТЬ
Я только что видел ваш код на StackBlitz, и проблема в том, что вы дважды отображаете шаблон выхода маршрутизатора в шаблоне. Вам нужно отображать то или иное в зависимости от условия. Я изменил ваш StackBlitz здесь с помощью переменной, которая будет отображать тот или иной выход маршрутизатора в зависимости от условия (вы можете проверить размер экрана или что угодно).
Но, просматривая ваш код, я не понимаю, зачем вам две розетки маршрутизатора... Если вы хотите запустить класс только в родительском div розетки маршрутизатора, вы можете просто использовать ngClass для использования того или иного класса на основе экрана размер.
Есть ли способ просто повторить одно и то же содержимое роутера-розетки? Я попытался поместить его в шаблон ng, но это тоже не сработало...
Почему бы нет? Если вы запускаете перенаправление маршрута из файлов .ts, вы можете проверить размер экрана и загрузить тот или иной маршрут в зависимости от размера экрана. В любом случае, рекомендуемый подход состоял бы в том, чтобы иметь два разных приложения...
Также да, я пробовал трюк с ng-template в более старом проекте, и он работал нормально... Можете ли вы поделиться некоторым кодом того, что вы пробовали в Stackblitz, чтобы помочь вам?
(Роутер-выход мне понадобился дважды, потому что html-шаблон достаточно сложный и сложный, чем в моем примере на stackblitz) Еще раз спасибо! :-)
У меня та же проблема, и использование разных маршрутов невозможно. Я попытался использовать пакет npm, который позволяет мне определять размеры экрана, но все равно правильно работает только второй выход, хотя в результирующем html есть только один выход.
Я думаю, что нашел другое решение, слушая Router-Events:
https://stackblitz.com/edit/router-outlet-twice-with-events
В этом stackblitz у меня на самом деле есть два шаблона, одновременно использующих router-outlet. Это допустимый обходной путь?
Пытаясь найти работу для этого, я закончил с:
HTML
<div id = "mobile">
<router-outlet *ngIf = "isMobile"></router-outlet>
</div>
<div id = "desktop">
<router-outlet *ngIf = "isDesktop"></router-outlet>
</div>
ТС
export class ExampleComponent implements AfterViewInit {
private initied: boolean
constructor (
private cdref: ChangeDetectorRef
) { }
ngAfterViewInit (): void {
this.initied = true
this.cdref.detectChanges()
}
get isDesktop (): boolean {
if (!this.initied) { return false }
return this.checkHidden('router-mobile')
}
get isMobile (): boolean {
if (!this.initied) { return false }
return this.checkHidden('router-desktop')
}
private checkHidden (id: string): boolean {
return (document.getElementById(id).getAttribute('style') as string).includes('display: none')
}
}
Я пробовал что-то вроде следующего и помогает мне показать взаимоисключающие
HTML
<div id = "mobile">
<router-outlet *ngIf = "!getIfMobile"></router-outlet>
</div>
<div id = "desktop">
<router-outlet *ngIf = "getIfMobile"></router-outlet>
</div>
Компонент.ts
get getIfMobile() {
return window.innerWidth < 720;
}
Хотя этот код может дать ответ на вопрос, предоставление дополнительного контекста относительно того, как и/или почему он решает проблему, улучшит долгосрочную ценность ответа.
Спасибо за Ваш ответ! К сожалению, я не могу использовать разные маршруты для разных размеров экрана...