Angular 路由器 : Redirect to an i18n URL

标签 angular angular-ui-router angular5

我有一个仅支持一种语言环境(法语)的 Angular 应用程序。然后我改进了应用程序以支持另一种语言,其中相同的组件在另一个根路径下可用 /ar

我现在的问题是应用程序使用了很多 [routerLink]="['some', 'thing'] 和其他 router.navigate('...')。我不是 i18n 所有链接,而是思考执行 url 翻译的聪明方法。

我做了以下事情:

this.translateService.onLangChange
.combineLatest(this.router.events)
.subscribe(([langEvent, event]) => {

    if (event instanceof NavigationStart) {
        let currentUrl = event.url;

        let locale = Locale.getLocaleByShortcut(langEvent.lang);

        if (locale) {
            if (locale.isArabic()) {
                if (!ContextUtils.isArabicUrl(currentUrl)) {
                    this.router.navigate(['/ar/' + currentUrl], {queryParams: this.route.snapshot.queryParams});
                }
            } else {
                if (ContextUtils.isArabicUrl(currentUrl)) {
                    let url = ContextUtils.frenchifyUrl(currentUrl);
                    this.router.navigate([url], {queryParams: this.route.snapshot.queryParams});
                }
            }
        }

    }

    if (event instanceof NavigationEnd) {

        if (Config.IS_WEB()) {
            $(document).ready(() =>
                setTimeout(() => {
                    Materialize.updateTextFields()
                }, 10)
            );
        }

        this.scrollToTop();
    }
});

问题是这个解决方案不能完美地工作,尤其是当从一个有 queryParams 的 url 导航到另一个没有它们的 url 时保留的 queryParams。

有什么聪明的方法可以为路由器导航到的 UrlSegments 添加前缀吗?

例子 <a[routerLink]="['some', 'thing']></a> ----> redirect to : /ar/some/thing设置 AR 语言环境时。和/some/thing 时不。

谢谢。

最佳答案

少了点东西

据我所知,Angular 没有提供任何将语言环境统一到一个网站中的东西。 Angular 要求您使用指定的区域设置参数进行多次构建。本质上,它们是托管在不同地址的不同网站。

还有其他使用管道的开源翻译解决方案。但我个人不愿意将第 3 方解决方案用于影响应用程序每个页面的内容。

我一直觉得着陆页会是一个有效的改进。那将是一个将这些站点链接在一起的 index.html 页面。例如然后你会有这样的设置:

index.html --> root landing page
en/
   index.html --> your angular site in English
   ...
fr/
   index.html --> your angular site in French.
   ...

主要的改进是,您可以在同一地址欢迎所有访客,并从那里无缝转发他们。

开源解决方案

我创建了一个要点,你可以找到它 here ,正是这样做的。这是一个可配置的着陆页。它是有意用纯 html 和 js 编写的。目的是使它成为您的根 index.html

因此,您可以轻松地在 1 个根域名下托管所有内容。但是,如果用户决定从一个语言环境切换到另一个语言环境,那仍然意味着要完全重新加载内存。但在正常情况下,用户只会更改一次语言。

基本工作

因此,如果有人只是导航到 http://example.com,它将尝试以多种方式(例如浏览器语言,...)确定该用户的语言,并且一次它知道该语言,它将使用预定义的路由配置将用户重定向到正确的 URL。在转发请求的同时,它还会转发子路径。 (在我的回答的最后部分对此进行了更多介绍)。

但它还会在本地存储中缓存语言,以供您下次访问。

现在,如果您希望您的用户选择一种语言,那么(例如在您的页面导航栏或设置 Pane 中)您可以添加一个链接,例如http://example.com/?locale=en。以这种方式指定的语言(即使用查询参数)将比浏览器语言或以前存储的语言具有更高的优先级。

要配置路由机制,您应该设置一个默认区域设置作为回退,并提供路由映射。

var defaultLocale = 'en';
var routing = {
  "en": 'https://example.com/en',
  "fr": 'https://example.com/fr'
  "en-uk": 'https://example.com/uk',
};

脚本将更喜欢完美的语言环境命中。但如果这没有产生匹配项,它将尝试仅使用该语言。 (尽管始终以小写形式定义它们)。

如何处理子路径

具体针对你的问题,转发是如何工作的。

无论您使用哪个网络服务器,对于 Angular 网络服务器都应该始终进行配置,以便所有子路径请求也被转发到您的 index.html。 (您当前的设置应该已经是这种情况。)

我们的着陆页 html 文件以相同的方式工作,它也接收完整路径。所以,当它想要提取子路径时,它实际上可以访问完整路径。它将通过删除第三个 / 后面的所有内容来提取子路径。

因此,如果您在 http://example.com 上托管此着陆页,并且您具有上述路由配置。然后,如果有人导航到 http://example.com/foo,并且该用户有英语语言环境,那么他将被重定向到 http://example.com/en/foo

关于 Angular 路由器 : Redirect to an i18n URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50632437/

相关文章:

angular - Angular 2+ 源代码中的 ɵ(类 Theta)符号

css - Angular:如何使用查询参数过滤数据表

html - ionic 3 html 按钮链接到 .ts 中的函数,但表示它未定义

angularjs - 页面刷新后 Angular UI 路由松散的 url 参数

Angular 5组件测试选择和触发事件

angular - 在 Angular 中创建嵌套模块是否正确

javascript - oidc-client 登录后重定向

javascript - 退出 ui-router 中的粘滞状态

javascript - Angular Jasmine UI 路由器将解析值注入(inject)测试

javascript - 无法将日历数据保存到 firebase 中