Как использовать несколько роутеров-розеток в angular2?
У меня есть основной router-outlet
, который используется для отображения экрана входа в систему (/login
) и экран основного контента (который отображается после входа в систему) (/main
).
Когда пользователь находится на экране контента, я хочу показать навигационную панель сверху с двумя вариантами (скажем, "Обзор", "Обзор"). Эта навигационная панель является общей для OverviewComponent
а также InsightsComponent
Ниже этой навигационной панели я хочу показать еще один роутер-розетку, который бы загружал OverviewComponent
или же InsightsComponent
, на основании чего пользователь нажимает в навигационной панели. Если я укажу "/ Overview" и / "Insights" в качестве маршрута, он будет показывать мне соответствующий компонент, но не панель навигации.
Следующее - моя текущая конфигурация маршрутизации (это не правильно):
const appRoutes: Routes = [
{ path: 'main', component: MainComponent},
{ path: 'overview', component: OverviewComponent},
{ path: 'insights', component: InsightsComponent },
{ path: 'login', component: LoginComponent },
{ path: '',
redirectTo: '/login',
pathMatch: 'full'
},
{ path: '**', component: PageNotFoundComponent }
];
Пожалуйста, дайте мне знать, если мы сможем добиться этого в angular2 angular4. Я использую следующую версию:
"@angular/core": "^4.0.0"
"@angular/router": "^4.0.0"
"@angular/cli": "1.0.1"
****************** Попытка 2 - все еще не работает ******************
const appRoutes: Routes = [
{ path: 'main',
children: [
{ path: '', component: MainComponent },
{ path: 'overview', component: OverviewComponent },
{ path: 'insights', component: InsightsComponent },
]
},
{ path: 'login', component: LoginComponent },
{ path: '',
redirectTo: '/login',
pathMatch: 'full'
},
{ path: '**', component: PageNotFoundComponent }
];
******* Попытка 2 - код Sudo со всеми компонентами - все еще не работает *******
//app.component.html
<router-outlet></router-outlet>
//app.module.ts
const appRoutes: Routes = [
{ path: 'main',
children: [
{ path: '', component: MainComponent },
{ path: 'overview', component: OverviewComponent },
{ path: 'insights', component: InsightsComponent },
]
},
{ path: 'login', component: LoginComponent },
{ path: '',
redirectTo: '/login',
pathMatch: 'full'
},
{ path: '**', component: PageNotFoundComponent }
];
//login.component.html
<div class="text-center vertical-center">
<form>
<div class="horizontal">
<label for="">Email</label>
<input class="form-control" type="text" name="" value="">
</div>
<div class="horizontal">
<label for="">Password</label>
<input class="form-control" type="password" name="" value="">
</div>
<button class="btn btn-primary" (click)="navigate()">Login</button>
</form>
</div>
//login.component.ts
navigate() {
this.router.navigate(['./main']);
}
//main.component.html
<app-header></app-header>
<router-outlet></router-outlet>
//app.header.html
<ul class="nav navbar-nav">
<li class=""><a routerLink="/main/overview" routerLinkActive="active">OVERVIEW</a></li>
<li class=""><a routerLink="/main/insights" routerLinkActive="active">INSIGHTS</a></li>
</ul>
//overview.html
<p>This is overview section</p>
//insights.html
<p>This is insights section</p>
******** Попытка 3 - Рабочая **********
const appRoutes: Routes = [
{ path: 'main', component: MainComponent,
children: [
{ path: '', component: MainComponent },
{ path: 'overview', component: OverviewComponent },
{ path: 'insights', component: InsightsComponent },
]
},
{ path: 'login', component: LoginComponent },
{ path: '',
redirectTo: '/login',
pathMatch: 'full'
},
{ path: '**', component: PageNotFoundComponent }
];
2 ответа
Так что, если я правильно понял вопрос, вы хотите, чтобы экран входа в систему первоначально и после входа в систему пользователя, вы хотите, чтобы он видел / main, где отображается навигация. И экран входа в систему, и основное приложение должны иметь разную компоновку.
У нас похожий случай и используется LayoutComponent. Вот упрощенный пример.
// This is main component that get's bootstrapped that has 'top-level' router.
@Component({selector: 'app', template: '<router-outlet></router-outlet>'})
class AppComponent {}
// main router config
// Here AuthModule has router with login and logout configured and LoginGuard
// redirect the user to /auth/login when she is not authenticated.
// We're using lazy-loading but you can use direct component instead
export const APP_ROUTES: Routes = [
{path: '', redirectTo: 'main', pathMatch: 'full'},
{path: 'auth', loadChildren: '../modules/+auth/auth.module#AuthModule'},
{
path: '',
component: LayoutComponent,
canActivate: [LoginGuard],
children: [
{path: 'main', loadChildren: '../modules/+main/main.module#MainModule'}
]
}
];
// AuthModule/LoginComponent has own template and it will be rendered
// into 'top-level' router-outlet.
// LayoutComponent
// Here you define your main application layout that can include navigation
// and anything else that are global to the app. It has another router-outlet
// that get rendered when the layout is accessible (which in this case when the user is authenticated).
@Component({
selector: 'app-layout',
template: `
<div id="wrapper">
<app-sidebar></app-sidebar>
<div id="page-wrapper" class="gray-bg dashboard-1" adjust-content-height>
<router-outlet></router-outlet>
</div>
</div>
<notifications></notifications>
<error-modal></error-modal>
`
})
export class LayoutComponent {}
// Auth/LoginComponent can have its own template that will have different layout from the main application
Так что поток будет выглядеть так:
- когда пользователь пытается загрузить / затем он перенаправлен на / main
- если пользователь не аутентифицирован, он перенаправляется в / auth / login, иначе он загружает / main
Надеюсь, это поможет.
РЕДАКТИРОВАТЬ: Обновлен репозиторий sickelap / ng-starter с примером приложения, которое имеет:
- маршрутизация с отложенной загрузкой
- макеты
- и другие вещи
Я думаю, я понимаю, что вы пытаетесь достичь. Могу ли я порекомендовать вам использовать переменную, чтобы имитировать какое-то изменение состояния, и назначить его представлению компонента. пусть ваш app.component.html содержит только выход маршрутизатора. создайте новый main.component.html, который копирует существующий component.html
`<app-header></app-header>`
заменить href на *(click)="handleChange(<linkValue>)'"
Поэтому каждая ссылка будет выглядеть так, как показано ниже.
<ul class="nav navbar-nav"> <li class=""><a href="/main/overview">OVERVIEW</a></li>
handleChange
метод: объявить currentLink - public currentLink string;
// or
public currentLink: string = '<a default value>';
public handleChange(link: string) {
this.currentLink = link;
}
создать view.component.
пример выбора <view [link]='currentLink'></view>
дать компоненту представления @Input() public link: string;
back to view.component.html
<div id="overview" *ngIf="link = 'overview'">overview content</div>
<div id="main" *ngIf="link = 'main'">overview content</div>
Затем вы можете преобразовать их в отдельные дочерние компоненты.
Обзор: вы делаете заголовок приложения глобальным компонентом, который обрабатывает переменную 'link'. Я бы порекомендовал взглянуть на ngRx или общие методы состояния приложения. Как это может быть отличным способом управления пользовательским интерфейсом.