角延迟加载模块无法导航到子路由

时间:2018-07-13 16:01:31

标签: angular routing routes lazy-loading

我正在创建一个仪表板应用程序,到目前为止,我有两个延迟加载的模块 AuthModuleAdminModule 我的app-routing-module.ts看起来像这样

const routes: Routes = [
    {
     path: '',
     loadChildren: './auth/auth.module#AuthModule'
    },
    {
     path: 'admin',
     loadChildren: './admin/admin.module#AdminModule',
     canActivate: [AuthGuardService]
    },
    {
      path: '**',
      component: NotFoundComponent
    }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})

我的app.component.html有一个<router-outlet></router-outlet>,应该在其中渲染上述路线。

因此这些网址在/auth//admin/上正常工作

在我的admin-routing.module.ts中,我有以下路线

const routes: Routes = [
  {
    path: '',
    component: AdminComponent,
    children: [
      {path: '', pathMatch: 'full', redirectTo: 'dashboard'},
      {path: 'dashboard', component: DashboardComponent },
      {path: 'users', component: UsersComponent },
      {path: 'reports', component: ReportsComponent },
      {path: 'booking', component: BookingComponent }
    ]
  }
];

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

这样/admin/路由可以直接导航到/admin/dashboard/,它也可以正常运行。

在我的admin.component.html中,我添加了另一个<router-outlet></router-outlet>,该AdminModule应该在其中渲染AdminModule路线,因此我可以使用sidenav栏布局。

问题在于,每当我尝试导航至其他任何/admin/dashboard之类的子路线时,只有router-outlet的默认路由/admin/users/会完美地呈现在第二个/admin/booking/内部或NotFoundComponent应用重定向到%/%

这是我的问题。 default child route for the admin module 'dashboard' trying to hit another child route

3 个答案:

答案 0 :(得分:0)

尝试

componentDidMount(){
  if(this.state.newData.length === 0){
    window.addEventListener('scroll', this.handleOnScroll);
    this.doQuery(1).then(res=>
      this.setState({
       newData: this.state.newData.slice().concat(res),
      requestSent: false
    }))
  }
}

componentWillUnmount() {
  window.removeEventListener('scroll', this.handleOnScroll);
}

handleOnScroll(){
  var scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
  var scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;
  var clientHeight = document.documentElement.clientHeight || window.innerHeight;
  var scrolledToBottom = Math.ceil(scrollTop + clientHeight) >= scrollHeight;
  if (scrolledToBottom) {
    this.setState({
      scrollCounter: this.state.scrollCounter + Math.floor(scrolledToBottom)
    },()=>{
            if(this.state.scrollCounter<4){
      this.doQuery(this.state.scrollCounter).then(res=>
      (res===BUSY)
        ? false
        : this.setState({
            newData: this.state.newData.slice().concat(res)
          })
        )
        .catch(err=>this.setState({requestSent: false}))
        this.setState({requestSent: true});
    }else{
      return true
    }
 })
  }
}

答案 1 :(得分:0)

您定义admin-routing.module.ts的方式意味着所有子路由都希望AdminComponent模板中包含一个元素。 Angular会尝试将所有子级呈现到AdminComponent中。

我有同样的问题。我没有设法在根路由器出口内呈现延迟加载的模块的子路由。我通过以下算法解决了这个问题:

对于应在c的出口中呈现的惰性加载模块M的每个子组件AppComponent

  • c创建一个延迟加载的模块
  • 在根目录下的app-routing.module中定义一条路径,该路径需要指向延迟加载的模块c的路径
  • M的路由声明中删除路由

对于admin/users,它可能看起来像这样:

app-routing-module.ts

const routes: Routes = [
    {
     path: '',
     loadChildren: './auth/auth.module#AuthModule'
    },
    {
     path: 'admin',
     loadChildren: './admin/admin.module#AdminModule',
     canActivate: [AuthGuardService]
    },
    {
     path: 'admin/users',
     loadChildren: './admin/users/admin-users.module#AdminUsersModule',
     canActivate: [AuthGuardService]
    },
    {
      path: '**',
      component: NotFoundComponent
    }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})

此解决方案有两个缺点:

  1. 您无法按预期封装模块,即父子语义丢失
  2. 您不能简单地重用父路径中反序列化的模块-如果您有深层嵌套

所以它不是理想的,但是可以。

答案 2 :(得分:0)

我终于找到了解决方案。

在您的app.module文件中,将代码更改如下:

   const routes: Routes = [
        {
         path: '',
         component: AuthComponent, //<--- Add this
         loadChildren: './auth/auth.module#AuthModule'
        },
        {
         path: 'admin',
         component: AdminComponent, //<--- Add this
         loadChildren: './admin/admin.module#AdminModule',
         canActivate: [AuthGuardService]
        },
        {
          path: '**',
          component: NotFoundComponent
        }
    ];

    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    }

)

在延迟加载的模块路由文件(admin-routing.module.ts)中,将代码更改为如下所示:

const routes: Routes = [

      {path: '', pathMatch: 'full', redirectTo: 'dashboard'},
      {path: 'dashboard', component: DashboardComponent },
      {path: 'users', component: UsersComponent },
      {path: 'reports', component: ReportsComponent },
      {path: 'booking', component: BookingComponent }

];

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

现在您的代码应该可以正常工作了