Изменение выхода маршрутизатора с помощью * ngIf в app.component.html в angular2
Я использую angular 2.0 final. Я пытаюсь изменить расположение маршрутизатора-выхода в главном app.component.html. Шаблон обновляет тонкий дисплей, за исключением того, что первый раз, когда я использую router.navigate, компонент не будет отображаться в новом маршрутизаторе-выходе, и нет ошибки. Второй и каждый раз, когда я использую router.navigate, он работает правильно.
пример шаблона app.component.html
<div *ngIf="authenticated() == false">
<h1>not logged in</h1>
<router-outlet>
</router-outlet>
</div>
<div *ngIf="authenticated()">
<h1>logged in</h1>
<router-outlet>
</router-outlet>
</div>
Ответы
Ответ 1
Я хотел бы сказать, пожалуйста, используйте имя router-outlet
, которое прекрасно работает, но проблема для меня в том, что такие URL совсем не удобны для пользователя, и я лично считаю, что URL с именем выхода не имеет смысла,
например: -
маршрут
{ path : "forgotPassword", component :ForgotPassword , outlet : "notlogedin" }
вывод в адресную строку браузера
http://localhost:4200/(notlogedin:forgotPassword)
посмотрим, как глупо это выглядит в адресной строке.
поэтому, если вы попытаетесь использовать *ngIf
для условного отключения и включения router-outlet
для решения проблемы, это не сработает. Один router-outlet
будет зарегистрирован, и независимо от того, что вы делаете, следующий router-outlet
не будет реагировать на изменения маршрута.
Итак, вот решение
Используя ngTemplateOutlet
и ng-template
, мы можем обеспечить хорошее решение этой проблемы, сохранив только один router-outlet
, см. ниже пример кода.
<ul>
<li><a routerLink="/login">login</a></li>
<li><a routerLink="/dashboard">dashboard</a></li>
</ul>
<!--This is where my before login router stays-->
<div class="logedIn-route" *ngIf="routerActive">
<ng-container *ngTemplateOutlet="template"></ng-container>
</div>
<!--This is where my after login router stays-->
<div class="logedout-route" *ngIf="!routerActive">
<ng-container *ngTemplateOutlet="template"></ng-container>
</div>
<ng-template #template>
<router-outlet>
</router-outlet>
</ng-template>
попробуй скрипку
https://jsfiddle.net/imal/e4tyqv95/36/
Ответ 2
Вместо этого вы должны рассмотреть использование named router-outlet
.
В документации сказано: Шаблон может содержать ровно один безымянный.
<div *ngIf="authenticated() == false">
<h1>not logged in</h1>
<router-outlet name="notloggedin">
</router-outlet>
</div>
<div *ngIf="authenticated()">
<h1>logged in</h1>
<router-outlet name="loggedin">
</router-outlet>
</div>
Маршрутизатор будет выглядеть так:
{ path: 'page1', component: Page1Component, outlet: 'notloggedin' },
{ path: 'page2', component: Page2Component, outlet: 'loggedin' }
Вот пример из @yurzui в этом посте.
Ответ 3
Мне пришлось использовать ViewContainerRef
, чтобы и на мобильном, и на настольном компьютере использовался один и тот же выход маршрутизатора:
<!-- MOBILE -->
<div *ngIf="isMobile">
<div #mobileOutlet></div>
</div>
<!-- DESKTOP -->
<div *ngIf="!isMobile">
<div #desktopOutlet></div>
</div>
<ng-template #tpl>
<router-outlet></router-outlet>
</ng-template>
И у меня не было проблем с использованием createEmbeddedView
для обоих:
@ViewChild('mobileOutlet', { read: ViewContainerRef }) _vcrMobile;
@ViewChild('desktopOutlet', { read: ViewContainerRef }) _vcrDesktop;
@ViewChild('tpl') tpl;
ngAfterViewInit() {
if (this.isMobile) this._vcrDesktop.createEmbeddedView(this.tpl);
else this._vcrMobile.createEmbeddedView(this.tpl);
}
единственное, что вам придется переключать эту розетку, если вы переключаетесь между контрольными точками. Например, изменение размера с рабочего стола на мобильный:
this._vcrDesktop.clear();
this._vcrMobile.createEmbeddedView(this.tpl)