角度路由器:重定向到i18n URL

时间:2018-05-31 20:39:13

标签: angular angular-ui-router angular5

我有一个只支持一个语言环境(法语)的角度应用程序。然后我演变了应用程序以支持另一种语言,其中相同的组件在另一个根路由/ar

下可用

我现在的问题是应用程序使用了很多[routerLink] =" [' some',' thing']和其他router.navigate(&#39 ; ...')。我没有使用所有链接,而是想出一种智能的方式来执行网址翻译。

我做了以下事情:

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添加前缀?

实施例 设置AR语言环境时<a[routerLink]="['some', 'thing']></a> ----> redirect to : /ar/some/thing。而不是/某些/事情。

谢谢。

1 个答案:

答案 0 :(得分:0)

缺少什么内容

据我所知,Angular并没有提供将语言环境统一到一个网站的功能。 Angular要求您使用指定的locale参数进行多个构建。本质上,它们是托管在不同地址上的不同网站。

还有其他使用管道的开源翻译解决方案。但是我个人不愿意使用第三方解决方案来解决影响应用程序每个页面的问题。

我总是觉得着陆页是一种有效的改进。那将是一个将这些站点链接在一起的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,它将尝试以几种方式(例如浏览器语言,...)确定该用户的语言,一旦知道该语言,它将使用< strong>预定义的路由配置,可将用户重定向到正确的网址。在转发请求时,它还将转发子路径。 (在我的答案的最后一部分中,关于它的更多内容)。

但是它还将语言存储在本地存储中,供您下次访问。

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

要配置路由机制,您应该设置一个默认的语言环境,该语言环境将作为后备,并提供路由映射。

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

该脚本将优先选择理想的语言环境。但是,如果不产生匹配项,它将尝试仅使用该语言。 (尽管始终将它们定义为小写)。

如何处理子路径

专门针对您的问题,转发是如何工作的。

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

我们的目标网页html文件以相同的方式工作,并且还接收完整路径。因此,当它想提取子路径时,实际上可以访问完整路径。并通过切出第三个/之后的所有内容来提取子路径。

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