【问题标题】:How to use multiple router-outlet in angular2?如何在angular2中使用多个路由器插座?
【发布时间】:2017-09-30 18:12:46
【问题描述】:

我有一个主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 }
];

【问题讨论】:

  • 我可以看看你的 main.component.html 是什么样的吗?
  • &lt;!--MainComponent.html--&gt; &lt;app-header&gt;&lt;/app-header&gt; &lt;router-outlet&gt;&lt;/router-outlet&gt; &lt;!--AppHeader.html--&gt; &lt;ul class="nav navbar-nav"&gt; &lt;li class=""&gt;&lt;a href="/main/overview"&gt;OVERVIEW&lt;/a&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;a href="/main/insights"&gt;INSIGHTS&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;
  • 无法通过在app-header中添加routerLink解决?如果它不起作用,您会遇到什么错误? - 您可以使用特定代码编辑问题。会很清楚。-
  • 您有两个选择:您可以定义子路由器插座或辅助(辅助)路由器插座。有关更多信息,请参阅文档:angular.io/docs/ts/latest/guide/router.html
  • 嗨 Saiyaff,我确实在 href 之前尝试了 routerLink,但也没有用。没有抛出错误。当我单击“概览”或“洞察”时,屏幕会显示概览或洞察组件,但不包含主组件中存在的标题。

标签: angular angular-cli router router-outlet


【解决方案1】:

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

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

用*(click)="handleChange(&lt;linkValue&gt;)'"替换href

所以每个链接如下所示。

&lt;ul class="nav navbar-nav"&gt; &lt;li class=""&gt;&lt;a href="/main/overview"&gt;OVERVIEW&lt;/a&gt;&lt;/li&gt;

handleChange 方法: 声明 currentLink - public currentLink string; // or public currentLink: string = '<a default value>'; public handleChange(link: string) { this.currentLink = link; }

创建一个view.component。

示例选择器&lt;view [link]='currentLink'&gt;&lt;/view&gt;

给视图组件一个 @Input() public link: string;

back to view.component.html 

&lt;div id="overview" *ngIf="link = 'overview'"&gt;overview content&lt;/div&gt; &lt;div id="main" *ngIf="link = 'main'"&gt;overview content&lt;/div&gt;

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

概述: 您正在使 app-header 成为处理“链接”变量的全局组件。我建议查看 ngRx 或一般的应用程序状态方法。因为这是管理 UI 的好方法。

【讨论】:

  • 感谢 Verix 的帮助,我现在可以正常工作了。但是,是的,这是一个潜在的替代方案,不过我会尝试一下。
  • 太棒了!如果您有时间,我想知道您的解决方案?我正在做很多状态管理和复杂的工作流程,所以这对我自己来说是一个不错的选择。但是,我很想有一个替代方案来申请!
  • 当然。我已经用我所有的尝试(使用 Sudo 代码)更新了我的问题。初期失败,然后崛起! ;)
【解决方案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_ROUTES 是在主 app.component.ts 中(代码中的内容)还是 app.module.ts 的一部分?
  • 我将 APP_ROUTES 保存在 app.routes.ts 文件中,并在 app.module.ts 中使用它们。回答完这个问题后,我开始认为分享项目结构作为工作示例以利用很多好东西来使用 Angular 是一个好主意。我知道有很多样板和启动器,但和其他人一样,我想这样做“My Way™”:) 我创建了 repo github.com/sickelap/ng-starter,它是空的 atm,但现在正在处理它,并且会有一些有用的东西几天后。
  • 太棒了,谢谢。是的,A2 中有很多很酷的东西,很多人都不知道,有时很难找到 sn-ps。您的入门工具包肯定会对许多人有所帮助。完成后请发表评论,以便我们所有人都可以查看。再次感谢。我喜欢“你的方式”;)
  • 使用示例应用更新了 repo。这是正在进行中的工作,我将不时更新它,使用我将提出的功能或建议。我很喜欢它
猜你喜欢
  • 2017-04-29
  • 2018-09-02
  • 2020-01-13
  • 1970-01-01
  • 2016-04-10
  • 2017-07-19
  • 2017-10-28
  • 1970-01-01
  • 2016-11-18
相关资源
最近更新 更多