当尝试设置路径时,出现“无法读取未定义的属性'loadChildren'”错误。

3
我需要有条件地加载路由路径。我尝试了以下方法,但是出现了这个错误。您能告诉我如何完成这样的任务吗?

[ng] 错误:无法读取未定义的 'loadChildren' 属性 [ng] i 「wdm」: 编译失败。

另外:

app-routing.module.ts:21 抛出类型错误:无法读取未定义的 'getLandingPage' 属性 at Module../src/app/app-routing.module.ts (app-routing.module.ts:21) at webpack_require (bootstrap:83) at Module../src/app/app.module.ts (app.component.ts:21) at webpack_require (bootstrap:83) at Module../src/main.ts (main.ts:1) at webpack_require (bootstrap:83) at Object.0 (main.ts:13) at webpack_require (bootstrap:83) at checkDeferredModules (bootstrap:45) at Array.webpackJsonpCallback [as push] (bootstrap:32)

app.routing.module.ts
const routes: Routes = [
  {
    path: "",
    redirectTo: this.getLandingPage(), // here is the issue
    pathMatch: "full",
  },
  {
   path: "tabs",
   loadChildren: "./pages/tabs/tabs.module#TabsPageModule",
  },
  {
   path: 'landing',
  loadChildren: './pages/landing/landing.module#LandingPageModule'
 },
];

export class AppRoutingModule {

  getLandingPage(): string {
    let url = "";
    switch (environment.hotelName) {
      case "h1":
        url = "tabs";
        break;
      case "h2":
        url = "landing";
        break;
      default:
    }
    return url;
  }


}

我有一个如下所示的 auth.gurad.ts 文件。我不确定在哪里可以使用它。

export class AuthGuard implements CanActivate {
  constructor(private router: Router,
    private user: UserService,
    private localStorageService: LocalStorageService) { }
  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
    return new Promise(async resolve => {
      const userInfo: UserInfo = await this.localStorageService.get(LocalStorage.USER_INFO);
      if (userInfo && (moment() < moment(userInfo.expireDate))) {
        this.user.guest = false;
        return resolve(true);
      }
      this.user.guest = true;
      this.router.navigate(["/sign-in"]);
      return resolve(false);
    });
  }
}

选项卡/着陆页的定义在哪里? - jcuypers
@jcuypers 已更新,请查看。 - Sampath
在 getLandingpage 中,您需要在 URL 前添加 / 前缀。 - jcuypers
你能否复制并粘贴“/pages/”的定义?你能确认目标是进行延迟加载吗? - jcuypers
@jcuypers 是的,这是惰性加载页面。 - Sampath
有没有可能只创建一个简单的 StackBlitz,因为很难确定所有部分是否都在那里。只需要基本的懒加载功能即可。 - jcuypers
5个回答

2
这与许多其他人遇到的逗号问题类似。请删除路由列表末尾的逗号,因为路由器认为有4个项目,最后一个是void 0/undefined项目,因此缺少loadChildren。 "Original Answer"翻译成"最初的回答"。
const routes: Routes = [
  {
    path: "",
    redirectTo: getLandingPage(),
    pathMatch: "full",
  },
  {
    path: "tabs",
    loadChildren: "./pages/tabs/tabs.module#TabsPageModule",
  },
  {
    path: 'landing',
    loadChildren: './pages/landing/landing.module#LandingPageModule'
  }
];

(注意在你的'landing'路由入口后缺少逗号)

最初的回答:请注意,在您的“landing”路由条目后缺少逗号。

2

检查路由配置中的编程逻辑

如果您在路由配置中使用除简单对象(具有字符串键和字符串值)之外的其他内容,则可能会出现此问题。


在我的情况下,当在某个路由的数据对象中设置正则表达式时,就会出现此问题:

{
  path: 'path', 
  component: MyComponent,
  data: {
    regEx: /^[a-f\d]{24}$/i,
  },
},

编译器无法处理此问题,只能报告不具描述性的错误:

错误:无法读取未定义的 'loadChildren' 属性


我发现其他人遇到的类似问题也与此相关。例如,在GitHub上,有人使用解析器的键常量。
const SOME_CONSTANT = 'someResolver',

{
  path: 'path',
  component: MyComponent,
  resolve: {
    [SOME_CONSTANT]: SomeResolver, // <-- you can't do this
  },
},

换句话说,当遇到这个问题时,请检查您是否以编程方式定义了路由器配置中的某些键、值或其他部分。

1
如果您正在使用路由守卫,为什么不在完全匹配的守卫中使用守卫,并从那里进行重定向?必要时使用条件语句。
示例:
const routes: Routes = [
  {
    path: "",
    canActivate: [RouteGuard]
 },
  {
   path: "tabs",
   loadChildren: "./pages/tabs/tabs.module#TabsPageModule",
  },
  {
   path: 'landing',
  loadChildren: './pages/landing/landing.module#LandingPageModule'
 },
];

RouteGuard:

 canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
    return new Promise(async resolve => {
        this.router.navigate([environment.hotelName]);
        resolve(true)
  }
}

0
你应该在 AppRoutingModule 之外定义 getLandingPage()
const getLandingPage = (): string => {
    let url = "";
    switch (hotelName) {
      case "h1":
        url = "tabs";
        break;
      case "h2":
        url = "landing";
        break;
      default:
    }
    return url;
  };

const routes: Routes = [
  {
    path: "",
    redirectTo: getLandingPage(),
    pathMatch: "full",
  },
  {
    path: "tabs",
    loadChildren: "./pages/tabs/tabs.module#TabsPageModule",
  },
  {
    path: 'landing',
    loadChildren: './pages/landing/landing.module#LandingPageModule'
  },
];

Stackblitz示例(https://stackblitz.com/edit/angular6-lazy-loading-hroo3l?file=src%2Fapp%2Fapp-routing.module.ts)使用const hotelName代替环境变量,因为Stackblitz没有定义环境变量。

同时也不确定它是否能与AOT很好地配合使用。


0
我今天遇到了同样的错误 'ERROR in Cannot read property 'loadChildren' of undefined'。

我认为这个错误可能有很多种情况。但对我来说,只是一个 CanActivate 类缺少 'export' 声明。

我的代码如下:

@Injectable({providedIn: 'root'})
class MyActivator implements CanActivate

实际上我应该有:

@Injectable({providedIn: 'root'})
export class MyActivator implements CanActivate

这个错误有点棘手!所以我想在这里提一下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接