如何在 Angular 7 中输入 Route 数据(在生产中)?

How to make Route data typed in Angular 7 (in production)?

import { environment } from '@env/environment';

export const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: 'organisations',
        component: OrganisationListComponent,
        data: {
          [environment.router.data.resourceName]: 'ORGANISATION' // <- error
        }
      },
      {
        path: 'organisations/create',
        component: OrganisationCreateComponent,
        data: {
          [environment.router.data.resourceName]: 'ORGANISATION_LIST' // <- error
        },...
      }

这是我的路由模块文件之一的一部分。如您所见,我希望路由数据有一个 属性 ,其名称是我在环境文件中定义的。但这在使用 --aot 标志编译时不起作用。这是错误:

ERROR in Error during template compile of 'AdminRoutingModule'
  Expression form not supported in 'routes'
    'routes' contains the error at app/admin/admin-routing.module.ts(30,11).

我的应用程序中有大约 30 条路由,所有路由都有数据 属性,键为 'resourceName'。而且我不想在我的应用程序中重复此字符串 30 次。

我无法创建具有 resourceName 属性 的 class 并在数据中实例化它,因为在路由配置中也不允许使用函数表达式。

有没有办法解决这个问题,或者根本不可能用 AOT 编译器实现?

编辑:这是 environement.ts 文件:

export const environment = {
  production: true,
  version: '1.0.0',
  router: {
    data: {
      resourceName: 'resourceName'
    }
  }
}

使用函数似乎可以解决这个棘手的问题。

function mydata() {
    return {[environment.router.data.resourceName]: 'ORGANISATION'};
}

export const routes: Routes = [
  {
    path: '',
    resolve: [TranslateResolver],
    children: [
      {
        path: 'organisations',
        component: OrganisationListComponent,
        canActivate: [RouteGuard],
        data: mydata()
      },...

我知道你试图将问题缩小到一个易于重现的问题,但也许你把它简化得太多了。

这样,从编译器错误消息中可以看出,这是不允许的(提供给 AOT 编译器的表达式,对象上的 [propertyName])。

我建议你完全避免这个问题,因为你可以有不同的环境文件,只需像这样定义数据:

export const environment = {
  production: true,
  version: '1.0.0',
  router: {
    data: {
      'resourceName': 'ORGANISATION', // <- replace 'resourceName' with whatever you need
    }
  }
}

然后像这样使用:

import { environment } from '@env/environment';

export const routes: Routes = [
  {
    path: '',
    resolve: [TranslateResolver],
    children: [
      {
        path: 'organisations',
        component: OrganisationListComponent,
        canActivate: [RouteGuard],
        data: environment.router.data,
      },...

如果你手头的问题需要其他东西,那么再次避免表达:

export const environment = {
  production: false,
  test: false,
  router: {
    data: {
      resourceName: 'resourceName', // <- replace 'resourceName' with whatever you need
    }
  },
};
export const environment = {
  production: true,
  version: '1.0.0',
  router: {
    data: {
      resourceName: environment.router.data.resourceName,
      value: 'ORGANIZATION',
    }
  }
}

这需要改变您使用这些数据的方式,但是,嘿,它有效。

声明您自己的 Route 数据类型。从 @angular/routerRoute 扩展,所以它都是类型安全的。这样,就可以断言 resourceName 属性 的存在,否则甚至可以省略。

过程中无需涉及环境模块。

import { RouterModule, Route } from '@angular/router';

export interface MyRoute extends Route {
    data: {
        resourceName: string;
    };
}

export declare type MyRoutes = MyRoute[];

export const routes: MyRoutes = [
  {
    path: '',
    children: [
      {
        path: 'organisations',
        component: OrganisationListComponent,
        data: {
          resourceName: 'ORGANISATION'
        }
      },
      {
        path: 'organisations/create',
        component: OrganisationCreateComponent,
        data: {
          resourceName: 'ORGANISATION_LIST'
        },...
      }