简体   繁体   English

默认路由重定向不适用于 Angular 2 中的延迟加载路由

[英]Default route redirect not working for lazy loaded routes in Angular 2

I have an app that is divided into a authenticated section (InternalRootComponent) and an anonymous section (ExternalRootComponent).我有一个应用程序,它分为经过身份验证的部分 (InternalRootComponent) 和匿名部分 (ExternalRootComponent)。

Everything works fine when I navigate to the routes explicitly, but when I go to the root (/), I don't get redirected.当我明确导航到路由时,一切正常,但是当我转到根 (/) 时,我没有被重定向。 Also, the AccountsComponent is loaded for some reason.此外,出于某种原因加载了 AccountsComponent。

app-routing.module.ts: app-routing.module.ts:

export const routes: Routes = [
    {
        path: '',
        redirectTo: 'login',
        pathMatch: 'full'
    },
    {
        path: 'login',
        component: ExternalRootComponent,
        children: [
            {
                path: '',
                loadChildren: './login/login.module#LoginModule'
            }
        ]
    },
    {
        path: 'membership',
        component: ExternalRootComponent,
        children: [
            {
                path: '',
                loadChildren: './membership/membership.module#MembershipModule'
            }
        ]
    },
    {
        path: 'app',
        component: InternalRootComponent,
        canActivate: [AuthGuard],
        children: [
            {
                path: '',
                canActivateChild: [AuthGuard],
                children: [
                    {
                        path: '',
                        redirectTo: './dashboard',
                        pathMatch: 'full'
                    },
                    {
                        path: 'dashboard',
                        loadChildren: './dashboard/dashboard.module#DashboardModule'
                    },
                    {
                        path: 'accounts',
                        loadChildren: './accounts/accounts.module#AccountsModule'
                    },
                    {
                        path: 'users',
                        loadChildren: './users/users.module#UsersModule'
                    },
                    {
                        path: 'services',
                        loadChildren: './services/services.module#ServicesModule'
                    },
                    {
                        path: 'support',
                        loadChildren: './support/support.module#SupportModule'
                    }
                ]
            }
        ]
    },
    {
        path: '**',
        component: NotFoundComponent
    }
];

accounts-routing.module.ts:账户-routing.module.ts:

const routes: Routes = [
    {
        path: '',
        component: AccountInfoComponent
    }
];

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

What I don't understand is why the first redirect doesn't work - I would expect / to redirect to /login.我不明白的是为什么第一个重定向不起作用 - 我希望 / 重定向到 /login。 Instead, it seems as if the empty route in accounts-routing.module.ts is being invoked.相反,似乎正在调用 accounts-routing.module.ts 中的空路由。

My guess is that AccountModule is imported into the root module.我的猜测是 AccountModule 被导入到根模块中。

This is a generic setup that should work.这是一个应该可以工作的通用设置。 Sorry I did not use all of your code because I thought it would be more clear with a minimum yet complete example.抱歉,我没有使用您的所有代码,因为我认为使用最少但完整的示例会更清楚。 I put comments of potential problems that would lead to the behavior you are observing.我对可能导致您正在观察的行为的潜在问题发表评论。 I can't be entirely sure this will solve your exact problem without more info but it is at the very least similar and should be helpful to somebody.我不能完全确定这会在没有更多信息的情况下解决您的确切问题,但它至少是相似的,应该对某人有所帮助。

take the following setup that uses module lazy loading:采用以下使用模块延迟加载的设置:

NOTE - lazy loading can lead to unexpected behavior because of the the router module importing of child routes, especially if you have services bundled into your feature modules which necessitates root level imports (probably best to separate the services into their own modules though).注意 - 由于路由器模块导入子路由,延迟加载可能导致意外行为,特别是如果您将服务捆绑到需要根级导入的功能模块中(可能最好将服务分离到它们自己的模块中)。 Comments below should explain what I mean by this.下面的评论应该解释我的意思。

The lesson is to only import lazy modules with routes once.教训是只导入带有路由的惰性模块一次。 (Not doing so means the module can no longer be lazy and defeats the purpose of the lazy loading altogether) if you have services bundled in with them that need to be in the root separate those into a different service module for the root (不这样做意味着模块不再是懒惰的,并且完全违背了延迟加载的目的)如果您捆绑了需要在根目录中的服务,将它们分离到根目录的不同服务模块中

app.module.ts app.module.ts

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component.ts';
import { routes } from './app-routing.module';

@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot(routes),
    // I think this might be your issue.
    // DON'T do this (import child module here)
    //
    // MaleChildModule
    // or somethings like this
    // FemaleChildModule.forRoot()
    //
    // NOTE - order doesn't matter either. i.e. putting this on the
    // line above RouterModule.forRoot(routes) will not help
    // 
    // Doing so means the ChildModules and routes are actually being
    // imported twice
    //
    // so these would all be valid paths
    // /female/sally
    // /sally
    // /male/john
    // /john
    //
    // then if you had a module's routes set up like those in 
    // the MaleChildModule the root redirect to /child
    // would not work and it would just be a blank view with no path
    // update in the browser. very confusing situation.
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

app.component.ts app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'ex-app',
  template: '<router-outlet></router-outlet>'
})
export class AppComponent {}

app-routing.module.ts app-routing.module.ts

import { Routes } from '@angular/router';

export const routes: Routes = [
  {
    path: '',
    pathMatch: 'full',
    redirectTo: 'males'
  },
  {
    path: 'males',
    loadChildren: './male-child.module#MaleChildModule'
  },
  {
    path: 'females',
    loadChildren: './female-child.module#FemaleChildModule'
  }
]

NOTE - lazy loaded modules import RouterModule.forChild(routes) which can lead to unexpected behavior if not careful注意 - 延迟加载的模块导入 RouterModule.forChild(routes) 如果不小心可能会导致意外行为

male-child.module.ts男性-child.module.ts

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

import { JohnChildComponent } from './john-child.component.ts';

// NOTE - if you set up your child module like this and make the
// mistake I'm describing (importing child modules multiple times)
// you will get unexpected behavior of redirects not working and
// no clues as to why. I suggest always having empty paths redirect
// to something with a component. FemaleChildModule is an example.
const childRoutes: Routes = [
  {
    path: 'john',
    component: JohnChildComponent
  }
]

@NgModule({
  imports: [
    RouterModule.forChild(childRoutes)
  ],
  declarations: [
    JohnChildComponent
  ]
})
export class MaleChildModule {}

female-child.module.ts女性-child.module.ts

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

import { SallyChildComponent } from './sally-child.component.ts';

const childRoutes: Routes = [
  {
    path: '',
    children: [
      // NOTE - I like to setup lazy loaded modules like this because
      // it prevents masking of the module loading issue because there
      // are never any paths that don't have an associated component
      {
        path: '',
        pathMatch: 'full',
        redirectTo: 'sally',
      },
      {
        path: 'sally',
        component: SallyChildComponent
      }
   ]
  }
]

@NgModule({
  imports: [
    RouterModule.forChild(childRoutes)
  ],
  declarations: [
    SallyChildComponent
  ]
})
export class FemailChildModule {}

john-child.component.ts john-child.component.ts

import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'ex-john',
  template: '<p>john</p>'
})
export class JohnChildComponent {}

sally-child.component.ts sally-child.component.ts

import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'ex-sally',
  template: '<p>sally</p>'
})
export class SallyChildComponent {}

If you're using lazy loading routes, the Global routes must also be included in app.module.ts in order the redirectTo and other routes functionality to work everywhere in the app module.如果您使用延迟加载路由,则还必须在 app.module.ts 中包含全局路由,以便redirectTo和其他路由功能在应用程序模块中的任何地方都能工作。

I architected my project where the coreModule is outsourced from the appModule where the main routes is imported in it我设计了我的项目,其中 coreModule 是从 appModule 外包的,主要路由是在其中导入的

图片

And in my appModule the coreModule is imported as well as the 'AppRoutingModule' (my main routes)在我的 appModule 中,导入了 coreModule 以及“AppRoutingModule”(我的主要路线)

图片

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM