如何在angular2中使用多个路由器插座?
How to use multiple router-outlet in angular2?
我有一个主 router-outlet
,用于显示登录屏幕 (/login
) 和主要内容屏幕(登录后显示)(/main
)。
一旦用户进入内容屏幕,我想在顶部显示一个导航栏,其中有 2 个选项(例如,'Overview'、'Insights')。此导航栏在 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 }
];
我想我收集到了你想要达到的目标。我可以建议您使用变量来模拟某种状态更改,并将其分配给组件视图吗?
让你的 app.component.html 只包含一个路由器插座。
创建一个新的 main.component.html 来复制现有的 component.html
`<app-header></app-header>`
将 href 替换为 *(click)="handleChange(<linkValue>)'"
所以每个 link 看起来如下。
<ul class="nav navbar-nav"> <li class=""><a href="/main/overview">OVERVIEW</a></li>
handleChange
方法:
声明当前链接 - 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>
然后您可以将它们重构为单独的子组件。
概览:
您正在使 app-header 成为处理 'link' 变量的全局组件。我会建议查看 ngRx 或一般的应用程序状态方法。因为这可能是管理 UI.
的好方法
因此,如果我答对了问题,您希望最初拥有登录屏幕,并且在用户登录后,您希望他看到显示导航的 /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 存储库:
- 延迟加载路由
- 布局
- 和其他东西
我有一个主 router-outlet
,用于显示登录屏幕 (/login
) 和主要内容屏幕(登录后显示)(/main
)。
一旦用户进入内容屏幕,我想在顶部显示一个导航栏,其中有 2 个选项(例如,'Overview'、'Insights')。此导航栏在 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 }
];
我想我收集到了你想要达到的目标。我可以建议您使用变量来模拟某种状态更改,并将其分配给组件视图吗? 让你的 app.component.html 只包含一个路由器插座。 创建一个新的 main.component.html 来复制现有的 component.html
`<app-header></app-header>`
将 href 替换为 *(click)="handleChange(<linkValue>)'"
所以每个 link 看起来如下。
<ul class="nav navbar-nav"> <li class=""><a href="/main/overview">OVERVIEW</a></li>
handleChange
方法:
声明当前链接 - 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>
然后您可以将它们重构为单独的子组件。
概览: 您正在使 app-header 成为处理 'link' 变量的全局组件。我会建议查看 ngRx 或一般的应用程序状态方法。因为这可能是管理 UI.
的好方法因此,如果我答对了问题,您希望最初拥有登录屏幕,并且在用户登录后,您希望他看到显示导航的 /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 存储库:
- 延迟加载路由
- 布局
- 和其他东西