如何在angular2中使用多个路由器插座?

时间:2017-05-03 04:33:50

标签: angular angular-cli router router-outlet

我有一个主router-outlet,用于显示登录屏幕(/login)和主要内容屏幕(登录后显示)(/main)。

用户在内容屏幕上,我想在顶部显示导航栏,有2个选项(例如,“概述”,“洞察”)。此导航栏对OverviewComponentInsightsComponent

很常见

在此导航栏下方,我想显示另一个路由器插座,它会根据用户在导航栏中的点击次数加载OverviewComponentInsightsComponent。如果我将'/ 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 个答案:

答案 0 :(得分:6)

因此,如果我得到正确的问题,您希望最初拥有登录屏幕,并且在用户登录后,您希望他看到/主显示导航的位置。登录屏幕和主应用程序都应该有不同的布局。

我们有类似的情况并使用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存储库:

  • 使用延迟加载进行路由
  • 布局
  • 和其他东西

答案 1 :(得分:0)

我想我会收集你想要达到的目标。我是否可以建议您使用变量来模拟某种状态更改,并将其分配给组件视图。   让你的app.component.html只包含一个路由器插座。   创建一个复制现有component.html的新main.component.html

`<app-header></app-header>`

替换with * (click)="handleChange(<linkValue>)'"

中的href

所以每个链接看起来如下。

<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>

然后,您可以将它们重构为单独的子组件。

概述:    您正在使app-header成为处理“link”变量的全局组件。我建议看看ngRx或一般的app-state方法。因为这可以是管​​理UI的好方法。