Angular 2子应用程序,父/子,嵌套组件,嵌套路由器插座,设计/编码 [英] Angular 2 sub apps, parent/child, nested components, nested router-outlet, design/coding

查看:83
本文介绍了Angular 2子应用程序,父/子,嵌套组件,嵌套路由器插座,设计/编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Angular 2应用程序。主屏幕(app?)看起来像这样......





当您单击顶级菜单routerLinks中的项目时,新组件将加载到主视图路由器插座中。其中一个链接加载一个新的管理模块/组件,它有自己的路由和新的路由器插座......





然后当你点击左侧导航栏中的routerLinks时,新的管理员组件将加载到新的路由器插座。



但是......



Angular 2不允许超过1个路由器插座。因此,点击左侧导航栏中的任何routerLink只会替换整个初始路由器插座视图。



我在使用bootstrap时看到了一些SO帖子(较旧,可能已弃用)加载后续组件,但我不能让它工作。我甚至不能从'任何地方导入{bootstrap},没有任何作用'。所以也许这不是这样做的方式。



如何让Admin子应用程序部分工作?



<非常感谢您分享您的Angular 2专业知识: - )



编辑:尝试以下建议的解决方案。无论我在哪里将路由放在app.routes.ts基础或子应用程序admin.routes.ts中,无论我如何格式化routerLinks,我都会收到此错误...





再次编辑:这是路由器和模板中的代码...

 <! -  
============== ================================================== ============
/src/app/component/admin/admin.component.html
- >

<! - 整页显示行显示 - >
< div class =row>

<! - 第1栏:左侧导航,指向所有管理组件的链接 - >
< div class =col col-md-4>
< app-admin-nav>< / app-admin-nav>
< / div>

<! - 第2列:记录行,点击进行编辑 - >
< div class =col col-md-8>
< router-outlet name =admin-app>< / router-outlet>
< / div>

< / div>

// ======================================== ====================================
// /src/app/app.routes .ts

从'@ angular / core'导入{ModuleWithProviders};
从'@ angular / router'导入{Routes,RouterModule};来自'./app.component'的
import {AppComponent};来自'./component/game/game.component'的
import {GameComponent};来自'./component/home/home.component'的
import {HomeComponent};
从'./component/login/login.component'导入{LoginComponent};来自'./component/player/player.component'的
import {PlayerComponent};来自'./service/auth/auth.service'的
import {AuthGuard};来自'./component/signup/signup.component'的
import {SignupComponent};来自'./component/email/email.component'的
import {EmailComponent};
从'./component/admin/admin.component'导入{AdminComponent};
//从'./component/admin/world/admin-world.component'导入{AdminWorldComponent};
//从'./component/admin/module/admin-module.component'导入{AdminModuleComponent};
//从'./component/admin/region/admin-region.component'导入{AdminRegionComponent};

export const router:Routes = [
{path:'',redirectTo:'home',pathMatch:'full'}
,{path:'home',component :HomeComponent}
,{path:'game',component:GameComponent,canActivate:[AuthGuard]}
,{path:'admin',component:AdminComponent,canActivate:[AuthGuard]}
//,{
//路径:'admin',组件:AdminComponent,canActivate:[AuthGuard],
// children:[
// {path:'world',component :AdminWorldComponent,outlet:'admin-app'},
// {path:'module',component:AdminModuleComponent,outlet:'admin-app'},
// {path:'region' ,组件:AdminRegionComponent,outlet:'admin-app'}
//]
//},
,{path:'login',component:LoginComponent}
,{ path:'signup',component:SignupComponent}
,{path:'login-email',component:EmailComponent}
,{路径:'玩家',组件:PlayerComponent,canActivate:[AuthGuard]}
];

export const routes:ModuleWithProviders = RouterModule.forRoot(router);

// ======================================== ====================================
// / src / app / component / admin /admin.routes.ts

从'@ angular / core'导入{ModuleWithProviders};
从'@ angular / router'导入{Routes,RouterModule};

从'./admin.component'导入{AdminComponent};来自'./world/admin-world.component'的
import {AdminWorldComponent};来自'./module/admin-module.component'的
import {AdminModuleComponent};来自'./region/admin-region.component'的
import {AdminRegionComponent};

export const router:Routes = [
{
path:'admin',component:AdminComponent,
children:[
{path:'world ',组件:AdminWorldComponent,outlet:'admin-app'}
,{path:'module',component:AdminModuleComponent,outlet:'admin-app'}
,{path:'region',组件:AdminRegionComponent,outlet:'admin-app'}
]
}
];

export const routes:ModuleWithProviders = RouterModule.forRoot(router);

编辑3:尝试更改 RouterModule.forRoot RouterModule.forChild ,遗憾的是,同样的错误: - /



编辑4:转换路由以使用2个路由模块。希望这可能会有所不同,但同样的错误。



新路由器...

  // ================================== ========================================== 
// / src /app/app-routing.module.ts

从'@ angular / core'导入{NgModule};来自'@ angular / router'的
import {RouterModule,Routes};来自'./app.component'的
import {AppComponent};来自'./component/game/game.component'的
import {GameComponent};来自'./component/home/home.component'的
import {HomeComponent};
从'./component/login/login.component'导入{LoginComponent};来自'./component/player/player.component'的
import {PlayerComponent};来自'./service/auth/auth.service'的
import {AuthGuard};来自'./component/signup/signup.component'的
import {SignupComponent};来自'./component/email/email.component'的
import {EmailComponent};
从'./component/admin/admin.component'导入{AdminComponent};

export const appRoutes:Routes = [
{path:'',redirectTo:'home',pathMatch:'full'}
,{path:'home',component :HomeComponent}
,{path:'game',component:GameComponent,canActivate:[AuthGuard]}
,{path:'admin',component:AdminComponent,canActivate:[AuthGuard]}
//,{
//路径:'admin',组件:AdminComponent,canActivate:[AuthGuard],
// children:[
// {path:'world',component :AdminWorldComponent,outlet:'admin-app'},
// {path:'module',component:AdminModuleComponent,outlet:'admin-app'},
// {path:'region' ,组件:AdminRegionComponent,outlet:'admin-app'}
//]
//},
,{path:'login',component:LoginComponent}
,{ path:'signup',component:SignupComponent}
,{path:'login-email',component:EmailComponent }
,{路径:'玩家',组件:PlayerComponent,canActivate:[AuthGuard]}
];

@NgModule({
进口:[
RouterModule.forRoot(appRoutes)
],
出口:[
RouterModule
]
})
导出类AppRoutingModule {}

// ======================= ================================================== ===
// /src/app/admin/admin-routing.module.ts

从'@ angular / core'导入{NgModule};来自'@ angular / router'的
import {RouterModule,Routes};
从'./admin.component'导入{AdminComponent};来自'./world/admin-world.component'的
import {AdminWorldComponent};来自'./module/admin-module.component'的
import {AdminModuleComponent};来自'./region/admin-region.component'的
import {AdminRegionComponent};

export const adminRoutes:Routes = [
{
path:'admin',component:AdminComponent,
children:[
{path:'world ',组件:AdminWorldComponent,outlet:'admin-app'}
,{path:'module',component:AdminModuleComponent,outlet:'admin-app'}
,{path:'region',组件:AdminRegionComponent,outlet:'admin-app'}
]
}
];

@NgModule({
进口:[
RouterModule.forChild(adminRoutes)
],
出口:[
RouterModule
]
})
导出类AdminRoutingModule {}

编辑5:它正在工作!



删除了路由模块,根据Tyler的建议返回到导出路由配置。他是对的,路由模块工作。泰勒和我一起工作很多,所以我接受了他的回答。谢谢泰勒的帮助!



以下是如何使用自己的路由器插座设置父应用程序,然后在父母点击链接以使用自己的新路由器加载子应用程序 - 出口。子应用程序加载/替换父应用程序路由器插座。



父应用程序模块或路由中没有什么特别之处。他们就是我在这篇文章之前的方式。



需要注意的重要事项,至少在今天的情况下,不要在子路由器插座中使用 name = attrib。这将导致错误:无法匹配任何路线......。 不要使用像我上面尝试过的路由模块,这也会导致错误:无法匹配任何路由......。 不要在路由中使用 outlet:'blah',这也会导致错误:无法匹配任何路由......。确保设置子路由配置 children:[] 完全如下所示在admin.routes.ts中。另外,请注意子路由中的 RouterModule.forChild(路由器)。这些事情为我今天解决了这个问题。



家长APP

  // ================================================== ========================== 
// src / app / app.module.ts

import来自'@ angular / core'的{NgModule};来自'@ angular / platform-b​​rowser'的
import {BrowserModule};来自'@ angular / forms'的
import {FormsModule};来自'@ angular / http'的
import {HttpModule};来自'angularfire2'的
import {AngularFireModule};来自'../environments/firebase.config'的
import {firebaseConfig};来自'@ ng-bootstrap / ng-bootstrap'的
import {NgbModule};
//从'./app-routing.module'导入{AppRoutingModule};
从'./app.routes'导入{routes};

//组件
从'./app.component'导入{AppComponent};来自'./component/home/home.component'的
import {HomeComponent};来自'./component/game/game.component'的
import {GameComponent};来自'./component/player/player.component'的
import {PlayerComponent};
从'./component/login/login.component'导入{LoginComponent};来自'./component/signup/signup.component'的
import {SignupComponent};来自'./component/email/email.component'的
import {EmailComponent};

//管理模块
从'./component/admin/admin.module'导入{AdminModule};

//来自'./service/auth/auth.service'的服务
import {AuthGuard};来自'./service/auth/auth-player.service'的
import {AuthPlayerService};来自'./service/mongo/mdb.service'的
import {MdbService};来自'./service/mongo/player-mdb.service'的
import {PlayerMdbService};

@NgModule({
声明:[
AppComponent
,HomeComponent
,GameComponent
,PlayerComponent
,LoginComponent
,SignupComponent
,EmailComponent
],
导入:[
BrowserModule
,FormsModule
,HttpModule
,AdminModule
,AngularFireModule.initializeApp(firebaseConfig)
,NgbModule.forRoot()
//,AppRoutingModule
,路由
],
提供商:[
AuthGuard
,AuthPlayerService
,MdbService
,PlayerMdbService
],
bootstrap:[AppComponent]
})
export class AppModule {}

// =========================================== =================================
// /src/app/app.routes.ts

从'@ angular / core'导入{ModuleWithProviders};
从'@ angular / router'导入{Routes,RouterModule};来自'./app.component'的

import {AppComponent};来自'./component/game/game.component'的
import {GameComponent};来自'./component/home/home.component'的
import {HomeComponent};
从'./component/login/login.component'导入{LoginComponent};来自'./component/player/player.component'的
import {PlayerComponent};来自'./service/auth/auth.service'的
import {AuthGuard};来自'./component/signup/signup.component'的
import {SignupComponent};来自'./component/email/email.component'的
import {EmailComponent};
从'./component/admin/admin.component'导入{AdminComponent};

export const router:Routes = [
{path:'',redirectTo:'home',pathMatch:'full'},
{path:'home',component :HomeComponent},
{路径:'游戏',组件:GameComponent,canActivate:[AuthGuard]},
{路径:'admin',组件:AdminComponent,canActivate:[AuthGuard]},
{path:'login',component:LoginComponent},
{path:'signup',component:SignupComponent},
{path:'login-email',component:EmailComponent},
{path:'players',component:PlayerComponent,canActivate:[AuthGuard]}
];

export const routes:ModuleWithProviders = RouterModule.forRoot(router);

CHILD APP

  // ==================================== ======================================== 
// / src / app /admin/admin.module.ts

从'@ angular / core'导入{NgModule,CUSTOM_ELEMENTS_SCHEMA};来自'@ angular / forms'的
import {FormsModule};来自'@ angular / common'的
import {CommonModule};
从'./admin.routes'导入{routes};
//从'./admin-routing.module'导入{AdminRoutingModule};
从'./admin.component'导入{AdminComponent};
从'./admin-recs.component'导入{AdminRecsComponent};来自'./admin-form.component'的
import {AdminFormComponent};
从'./admin-nav.component'导入{AdminNavComponent};

从'./world/admin-world.component'导入{AdminWorldComponent};来自'./module/admin-module.component'的
import {AdminModuleComponent};来自'./region/admin-region.component'的
import {AdminRegionComponent};

@NgModule({
进口:[
CommonModule
,FormsModule
//,AdminRoutingModule
,路线
]
,声明:[
AdminComponent
,AdminNavComponent
,AdminRecsComponent
,AdminFormComponent
,AdminWorldComponent
,AdminModuleComponent
,AdminRegionComponent
]
,架构:[CUSTOM_ELEMENTS_SCHEMA]
,出口:[
AdminRecsComponent
,AdminFormComponent
,AdminNavComponent
//,AdminWorldComponent
//,AdminModuleComponent
//,AdminRegionComponent
]
//,bootstrap:[AdminComponent]
})
导出类AdminModule {}


// ========================================== ==================================
// /scr/app/admin/admin.routes .ts

import {ModuleWithProviders} from @角/芯;
从'@ angular / router'导入{Routes,RouterModule};

从'./admin.component'导入{AdminComponent};来自'./world/admin-world.component'的
import {AdminWorldComponent};来自'./module/admin-module.component'的
import {AdminModuleComponent};来自'./region/admin-region.component'的
import {AdminRegionComponent};

export const router:Routes = [
{
path:'admin',component:AdminComponent,
children:[
{path:'world ',component:AdminWorldComponent},
{path:'module',component:AdminModuleComponent},
{path:'region',component:AdminRegionComponent},
]
}
];

export const routes:ModuleWithProviders = RouterModule.forChild(router);


解决方案

不知道你在哪里听说Angular2不允许更多超过1 router-outlet 。我在一个大型应用程序中使用了几个。



你的主app.component将有一个 router-outlet 来处理根路由。如果您的某个路由延迟加载管理模块,那么该管理模块将拥有包含侧面菜单栏的根组件以及所有子路由的 router-outlet



示例:



// app.routes

  export const ROUTES:Routes = [
//主重定向
{路径:'',组件:MainViewComponent},

{
路径:'admin',
loadChildren:'。/ admin / admin.module #AdminModule'
}
]

您的MainViewComponent可以包含顶部导航栏和路由器插座



然后管理员路由器配置可能如下所示:

  export const routes:Routes = [
{
路径:'',
组件:AdminComponent,
children:[
{path:'',component:Component1},
{path:' component2',component:Component2}

]
}
];

管理模块中的根组件可能包含侧栏菜单和 router-outlet 显示子组件。



你也可以命名 router-outlets 。一个例子是并排两个 router-outlet

 <路由器出口>< /路由器出口> 
< router-outlet name =popup>< / router-outlet>

您的路由器配置如下所示:

  {
路径:'compose',
组件:ComposeMessageComponent,
outlet:'popup'
},

您可以这样使用它:

 < a [routerLink] =[{outlets:{popup:['compose']}}]>联系< / a> 

或者用以下内容清除内容:

  this.router.navigate([{outlets:{popup:null}}]); 

参见 docs 或this 文章了解更多详情。



希望有所帮助。



修改



为延迟加载的子项使用路由配置时,请确保在模块中正确加载路由配置。根路由配置将加载到根AppModule中,带有 RouterModule.forRoot(路由),子路由在子模块中,带有 RouterModule.forChild (路线)



您的路线配置和模块需要如下所示(不要创建单独的模块来保存路由配置) :



//管理员路线

  export const adminRoutes:Routes = [
{
路径:'admin',组件:AdminComponent,
children:[
{路径:'world',组件:AdminWorldComponent,outlet:'admin-app'}
,{路径:'模块',组件:AdminModuleComponent,outlet:'admin-app'}
,{路径:'region',组件:AdminRegionComponent,outlet:'admin-app'}
]
}
];

//管理模块:

 从'./admin.routes'导入{adminRoutes}; 

@NgModule({
进口:[
...
RouterModule.forChild(adminRoutes),
]
...

// App Routes(延迟加载管理模块)

  export const appRoutes:Routes = [
{path:'admin',loadChildren:'。/ admin / admin.module #AdminModule'},
。 ...

//应用程序模块

 从'./app.routes'导入{appRoutes}; 

@NgModule({
进口:[
...
RouterModule.forRoot(appRoutes),
]
...

希望有所帮助。


I have an Angular 2 app. The main screen (app?) looks like this...

When you click items in the top menu routerLinks, new Components load into the main view router outlet. One of those links loads up an new "Admin" Module/Component with it's own routes and new router outlet...

Then when you click the routerLinks in the left nav, new admin Components will load in the new router outlet.

But...

Angular 2 does not allow more than 1 router outlet. So clicking on any routerLink in left nav simply replaces the entire inital router outlet view.

I've seen some SO posts (older, maybe deprecated) on using "bootstrap" to load subsequent Components, but I can't get that to work. I can't even import { bootstrap } from 'anywhere at all, nothing works'. So maybe that's not the way to do this.

How can I get the Admin sub app part to work?

Thank you very, very much for sharing your Angular 2 expertise :-)

EDIT: Trying suggested solutions below. No matter where I put the routes, in the base app.routes.ts or in the sub-app admin.routes.ts, no matter how I format the routerLinks, I keep getting this error...

EDIT AGAIN: Here is the code in the routers and the template...

<!--
    ============================================================================
    /src/app/component/admin/admin.component.html
-->

<!-- Row for entire page columnar dispaly -->
<div class="row">

    <!-- Column 1: Left navigation, links to all admin components -->
    <div class="col col-md-4">
        <app-admin-nav></app-admin-nav>
    </div>

    <!-- Column 2: Rows of records, click to edit -->
    <div class="col col-md-8">
        <router-outlet name="admin-app"></router-outlet>
    </div>

</div>

// ============================================================================
// /src/app/app.routes.ts

import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { GameComponent } from './component/game/game.component';
import { HomeComponent } from './component/home/home.component';
import { LoginComponent } from './component/login/login.component';
import { PlayerComponent } from './component/player/player.component';
import { AuthGuard } from './service/auth/auth.service';
import { SignupComponent } from './component/signup/signup.component';
import { EmailComponent } from './component/email/email.component';
import { AdminComponent } from './component/admin/admin.component';
// import { AdminWorldComponent } from './component/admin/world/admin-world.component';
// import { AdminModuleComponent } from './component/admin/module/admin-module.component';
// import { AdminRegionComponent } from './component/admin/region/admin-region.component';

export const router: Routes = [
    { path: '', redirectTo: 'home', pathMatch: 'full' }
    , { path: 'home', component: HomeComponent }
    , { path: 'game', component: GameComponent, canActivate: [AuthGuard] }
    , { path: 'admin', component: AdminComponent, canActivate: [AuthGuard] }
    // , {
    //     path: 'admin', component: AdminComponent, canActivate: [AuthGuard],
    //     children: [
    //         { path: 'world', component: AdminWorldComponent, outlet: 'admin-app' },
    //         { path: 'module', component: AdminModuleComponent, outlet: 'admin-app' },
    //         { path: 'region', component: AdminRegionComponent, outlet: 'admin-app' }
    //     ]
    // },
    , { path: 'login', component: LoginComponent }
    , { path: 'signup', component: SignupComponent }
    , { path: 'login-email', component: EmailComponent }
    , { path: 'players', component: PlayerComponent, canActivate: [AuthGuard] }
];

export const routes: ModuleWithProviders = RouterModule.forRoot(router);

// ============================================================================
// /src/app/component/admin/admin.routes.ts

import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { AdminComponent } from './admin.component';
import { AdminWorldComponent } from './world/admin-world.component';
import { AdminModuleComponent } from './module/admin-module.component';
import { AdminRegionComponent } from './region/admin-region.component';

export const router: Routes = [
    {
        path: 'admin', component: AdminComponent,
        children: [
            { path: 'world', component: AdminWorldComponent, outlet: 'admin-app' }
            , { path: 'module', component: AdminModuleComponent, outlet: 'admin-app' }
            , { path: 'region', component: AdminRegionComponent, outlet: 'admin-app' }
        ]
    }
];

export const routes: ModuleWithProviders = RouterModule.forRoot(router);

EDIT 3: Tried changing RouterModule.forRoot to RouterModule.forChild, sadly, same error :-/

EDIT 4: Converted routing to use 2 routing modules. Was hoping maybe that would make a difference, but same error.

New routers...

// ============================================================================
// /src/app/app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { GameComponent } from './component/game/game.component';
import { HomeComponent } from './component/home/home.component';
import { LoginComponent } from './component/login/login.component';
import { PlayerComponent } from './component/player/player.component';
import { AuthGuard } from './service/auth/auth.service';
import { SignupComponent } from './component/signup/signup.component';
import { EmailComponent } from './component/email/email.component';
import { AdminComponent } from './component/admin/admin.component';

export const appRoutes: Routes = [
    { path: '', redirectTo: 'home', pathMatch: 'full' }
    , { path: 'home', component: HomeComponent }
    , { path: 'game', component: GameComponent, canActivate: [AuthGuard] }
    , { path: 'admin', component: AdminComponent, canActivate: [AuthGuard] }
    // , {
    //     path: 'admin', component: AdminComponent, canActivate: [AuthGuard],
    //     children: [
    //         { path: 'world', component: AdminWorldComponent, outlet: 'admin-app' },
    //         { path: 'module', component: AdminModuleComponent, outlet: 'admin-app' },
    //         { path: 'region', component: AdminRegionComponent, outlet: 'admin-app' }
    //     ]
    // },
    , { path: 'login', component: LoginComponent }
    , { path: 'signup', component: SignupComponent }
    , { path: 'login-email', component: EmailComponent }
    , { path: 'players', component: PlayerComponent, canActivate: [AuthGuard] }
];

@NgModule({
    imports: [
        RouterModule.forRoot(appRoutes)
    ],
    exports: [
        RouterModule
    ]
})
export class AppRoutingModule { }

// ============================================================================
// /src/app/admin/admin-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AdminComponent } from './admin.component';
import { AdminWorldComponent } from './world/admin-world.component';
import { AdminModuleComponent } from './module/admin-module.component';
import { AdminRegionComponent } from './region/admin-region.component';

export const adminRoutes: Routes = [
    {
        path: 'admin', component: AdminComponent,
        children: [
            { path: 'world', component: AdminWorldComponent, outlet: 'admin-app' }
            , { path: 'module', component: AdminModuleComponent, outlet: 'admin-app' }
            , { path: 'region', component: AdminRegionComponent, outlet: 'admin-app' }
        ]
    }
];

@NgModule({
    imports: [
        RouterModule.forChild(adminRoutes)
    ],
    exports: [
        RouterModule
    ]
})
export class AdminRoutingModule { }

EDIT 5: IT'S WORKING!

Removed the routing modules, returned to exporting routes config per Tyler's suggestion. He is right, the routing modules do not work. Tyler worked with me a lot so I'm accepting his answer. Thank you Tyler for your help!

Here is how you can setup a parent app with it's own router-outlet, then on the parent click a link to load up a child app with it's own new router-outlet. The child app loads/replaces the parent app router-outlet.

There is really nothing special in the parent app module or routes. They're just how I had them before this post.

The important points to note, at least in my case today, do not use a name="" attrib in the child router-outlet. This will cause "Error: Cannot match any routes...". Do not use routing modules like I tried above, this also causes "Error: Cannot match any routes...". Do not use outlet: 'blah' in the routes, this also causes "Error: Cannot match any routes...". Make sure you set up the child route config children: [] exactly as you see below in admin.routes.ts. Also, note the RouterModule.forChild(router) in the child routes. These things fixed the issue for me today.

PARENT APP

// ============================================================================
// src/app/app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AngularFireModule } from 'angularfire2';
import { firebaseConfig } from '../environments/firebase.config';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
// import { AppRoutingModule } from './app-routing.module';
import { routes } from './app.routes';

// Components
import { AppComponent } from './app.component';
import { HomeComponent } from './component/home/home.component';
import { GameComponent } from './component/game/game.component';
import { PlayerComponent } from './component/player/player.component';
import { LoginComponent } from './component/login/login.component';
import { SignupComponent } from './component/signup/signup.component';
import { EmailComponent } from './component/email/email.component';

// Admin Module
import { AdminModule } from './component/admin/admin.module';

// Services
import { AuthGuard } from './service/auth/auth.service';
import { AuthPlayerService } from './service/auth/auth-player.service';
import { MdbService } from './service/mongo/mdb.service';
import { PlayerMdbService } from './service/mongo/player-mdb.service';

@NgModule({
    declarations: [
        AppComponent
        , HomeComponent
        , GameComponent
        , PlayerComponent
        , LoginComponent
        , SignupComponent
        , EmailComponent
    ],
    imports: [
        BrowserModule
        , FormsModule
        , HttpModule
        , AdminModule
        , AngularFireModule.initializeApp(firebaseConfig)
        , NgbModule.forRoot()
        // , AppRoutingModule
        , routes
    ],
    providers: [
        AuthGuard
        , AuthPlayerService
        , MdbService
        , PlayerMdbService
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

// ============================================================================
// /src/app/app.routes.ts

import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { GameComponent } from './component/game/game.component';
import { HomeComponent } from './component/home/home.component';
import { LoginComponent } from './component/login/login.component';
import { PlayerComponent } from './component/player/player.component';
import { AuthGuard } from './service/auth/auth.service';
import { SignupComponent } from './component/signup/signup.component';
import { EmailComponent } from './component/email/email.component';
import { AdminComponent } from './component/admin/admin.component';

export const router: Routes = [
    { path: '', redirectTo: 'home', pathMatch: 'full' },
    { path: 'home', component: HomeComponent },
    { path: 'game', component: GameComponent, canActivate: [AuthGuard] },
    { path: 'admin', component: AdminComponent, canActivate: [AuthGuard] },
    { path: 'login', component: LoginComponent },
    { path: 'signup', component: SignupComponent },
    { path: 'login-email', component: EmailComponent },
    { path: 'players', component: PlayerComponent, canActivate: [AuthGuard] }
];

export const routes: ModuleWithProviders = RouterModule.forRoot(router);

CHILD APP

// ============================================================================
// /src/app/admin/admin.module.ts

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { routes } from './admin.routes';
// import { AdminRoutingModule } from './admin-routing.module';
import { AdminComponent } from './admin.component';
import { AdminRecsComponent } from './admin-recs.component';
import { AdminFormComponent } from './admin-form.component';
import { AdminNavComponent } from './admin-nav.component';

import { AdminWorldComponent } from './world/admin-world.component';
import { AdminModuleComponent } from './module/admin-module.component';
import { AdminRegionComponent } from './region/admin-region.component';

@NgModule({
    imports: [
        CommonModule
        , FormsModule
        // , AdminRoutingModule
        , routes
    ]
    , declarations: [
        AdminComponent
        , AdminNavComponent
        , AdminRecsComponent
        , AdminFormComponent
        , AdminWorldComponent
        , AdminModuleComponent
        , AdminRegionComponent
    ]
    , schemas: [CUSTOM_ELEMENTS_SCHEMA]
    , exports: [
        AdminRecsComponent
        , AdminFormComponent
        , AdminNavComponent
        // , AdminWorldComponent
        // , AdminModuleComponent
        // , AdminRegionComponent
    ]
    // , bootstrap: [AdminComponent]
})
export class AdminModule { }


// ============================================================================
// /scr/app/admin/admin.routes.ts

import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { AdminComponent } from './admin.component';
import { AdminWorldComponent } from './world/admin-world.component';
import { AdminModuleComponent } from './module/admin-module.component';
import { AdminRegionComponent } from './region/admin-region.component';

export const router: Routes = [
    {
        path: 'admin', component: AdminComponent,
        children: [
            { path: 'world', component: AdminWorldComponent },
            { path: 'module', component: AdminModuleComponent },
            { path: 'region', component: AdminRegionComponent },
        ]
    }
];

export const routes: ModuleWithProviders = RouterModule.forChild(router);

解决方案

Not sure where you heard that Angular2 does not allow more than 1 router-outlet. I am using several in a large application.

Your main app.component will have a router-outlet to handle the root routes. If one of your routes lazy-loads the Admin Module, that admin module will have it's root component that contains the side menu bar and a router-outlet for all the children routes.

Example:

//app.routes

export const ROUTES: Routes = [
    // Main redirect
    { path: '', component: MainViewComponent },

    {
        path: 'admin',
        loadChildren: './admin/admin.module#AdminModule'
    }
]

Your MainViewComponent can contain the top navbar and a router-outlet.

Then the Admin router config may look like this:

export const routes: Routes = [
    {
        path: '',
        component: AdminComponent,
        children: [
            { path: '', component: Component1},
            { path: 'component2', component: Component2}

        ]
    }
];

Your root component in the Admin module may contain the side bar menu and a router-outlet to show the children components.

You can also do named router-outlets. An example of this is having two router-outlets side-by-side:

<router-outlet></router-outlet>
<router-outlet name="popup"></router-outlet>

Your router config would look like this:

{
  path: 'compose',
  component: ComposeMessageComponent,
  outlet: 'popup'
},

And you would use it like this:

<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>

Or clear the content with this:

this.router.navigate([{ outlets: { popup: null }}]);

See the docs or this article for more details.

Hope that helps.

Edit

When using the route config for a lazily loaded child, make sure your route configs are loaded properly in your modules. The root route config will be loaded in the root AppModule with RouterModule.forRoot(routes) and the child routes are in the Child module with RouterModule.forChild(routes).

Your route config and modules need to look like this(don't create a separate module just to hold routing config):

//Admin Routes

export const adminRoutes: Routes = [
    {
        path: 'admin', component: AdminComponent,
        children: [
            { path: 'world', component: AdminWorldComponent, outlet: 'admin-app' }
            , { path: 'module', component: AdminModuleComponent, outlet: 'admin-app' }
            , { path: 'region', component: AdminRegionComponent, outlet: 'admin-app' }
        ]
    }
];

//Admin Module:

import { adminRoutes } from './admin.routes';

@NgModule({
  imports: [
    ...
    RouterModule.forChild(adminRoutes),
  ]
   ...

//App Routes(lazy load Admin module)

export const appRoutes: Routes = [
   { path: 'admin', loadChildren: './admin/admin.module#AdminModule' },
   ....

//App Module

import { appRoutes } from './app.routes';

@NgModule({
  imports: [
    ...
    RouterModule.forRoot(appRoutes),
  ]
   ...

Hope that helps.

这篇关于Angular 2子应用程序,父/子,嵌套组件,嵌套路由器插座,设计/编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆