角度路由:是否可以为不同的语言使用不同的“路径”字符串?

时间:2017-05-10 23:16:14

标签: angular angular-routing

我正在做一个i18n Angular应用程序,到目前为止效果很好。

但是我有不同语言的相同路由字符串,这不是SEO的最佳选择。

对于每种语言,Routes数组的'path'属性是否可能不同?

实施例

const appRoutesEN: Routes = [
  { path: 'crisis-center', component: CrisisListComponent },
  { path: 'hero/:id',      component: HeroDetailComponent },
  {
    path: 'heroes',
    component: HeroListComponent,
    data: { title: 'Heroes List' }
  },
  { path: '**', component: PageNotFoundComponent }
];

是否可以定义appRoutesFR: Routes如果是,我可以如何使用它?我应该将LOCALE_ID注入路由模块吗?如果是这样的话?

3 个答案:

答案 0 :(得分:3)

如果您在评论中描述的每种语言需要不同的路由,则每种语言都可以使用专用路由模块。然后在angular-cli.json中为每种语言定义一个专用应用程序,使用它自己的main.ts和它自己的AppModule,只引入特定语言所需的路由模块。

  "apps": [
   {
      "root": "src",
      "name": "yourapp_FR",
...
      "main": "./app/yourapp_FR/main.ts",
...   
    },
   {
      "root": "src",
      "name": "yourapp_DE",
...
      "main": "./app/yourapp_DE/main.ts",
...   
    }
    ]

然后为每种语言构建应用程序,如下所示:

ng build --app yourapp_FR --i18n-file src/i18n/messages.fr.xlf --locale fr --i18n-format xlf --aot

这样你就可以设置一次,每次都可以构建而不会发表任何评论。 我没有完整的背景。你说每种语言的路由更适合SEO。我不明白这一点,但如果你这样说,好的。但是,我不喜欢每种语言的专用路由。这意味着需要大量冗余和更多维护。

答案 1 :(得分:1)

目前似乎没有简单的解决方案。如果我找到,我会更新。

Angular i18n正在努力整合代码级国际化,可能就是这样。

我能提出的最佳解决方案是更改代码中的路由模块和模板中的routerLink属性以及代码的其他部分中每种语言的所有链接,然后为每种语言构建应用程序分开。

根本不理想。

<强>更新

根据@estus的建议,我已尝试Greentube/localize-router

我很高兴安装@ngx-translate/core@ngx-translate/http-loader等依赖项,因为我使用的是Angular i18n实现/工具,而不是ngx-translate。

直到遇到lazy-loaded module with child routes为止。

因此,如果您没有任何带有子项的延迟加载模块,localize-router就可以了。

<强>更新

最新版本的localize-router现在支持延迟加载的模块。

一旦编程翻译到达,将支持Angular i18n。

答案 2 :(得分:0)

如果您已经在使用@ ngx-translate / core之类的东西,则可以创建自己的映射,而不必添加更多的外部库。

示例:

function generateI18nRoutes(
    elements: Array<{ i18nPaths: string[]; component: any; data: object; canActivate?: 
[] }>
): Routes {
    return elements.reduce(
        (accumulator, currentValue) => [
            ...accumulator,
            ...currentValue.i18nPaths.map((path: string) => ({
                path,
                component: currentValue.component,
                data: currentValue.data,
                canActivate: currentValue.canActivate
            }))
        ],
        []
    );
}

然后像这样使用它:

const routes: Routes = [
    {
        path: "admin",
        component: AdminLayoutComponent,
        canActivate: [AdminAuthGuard],
        children: generateI18nRoutes([{ i18nPaths: [""], component: HomeComponent, data: { title: "ADMIN" } }])
    },
    {
        path: "",
        component: GeneralLayoutComponent,
        children: generateI18nRoutes([
            { i18nPaths: [""], component: HomeComponent, data: { title: "HOME" } },
            {
                i18nPaths: ["sign-in", "iniciar-sesión", "iniciar-sessão"],
                component: SignInComponent,
                data: { title: "SIGN_IN" }
            }
        ])
    },
    {
        path: "**",
        component: PageNotFoundComponent,
        data: { title: "PAGE_NOT_FOUND" }
    }
];

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