Изменение выхода маршрутизатора с помощью * 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)