Javascript 带路径参数的angularjs i18n路由

Javascript 带路径参数的angularjs i18n路由,javascript,angularjs,routes,internationalization,ngroute,Javascript,Angularjs,Routes,Internationalization,Ngroute,在我正在使用的一个应用程序中,路由系统需要与i18n集成,如下例所示: $routeProvider.when('/:i18n/section', ...); 但是我面临一些问题,我猜是由于$digest循环,它在运行时不会更改i18n参数 我面临的另一个问题是,如果位置路径指向以下内容: http://localhost:9000/section/... 不像: http://localhost:9000/en/section/... i18n路径参数结束时与/section/关联,这意

在我正在使用的一个应用程序中,路由系统需要与i18n集成,如下例所示:

$routeProvider.when('/:i18n/section', ...);
但是我面临一些问题,我猜是由于
$digest
循环,它在运行时不会更改
i18n
参数

我面临的另一个问题是,如果位置路径指向以下内容:

http://localhost:9000/section/...
不像:

http://localhost:9000/en/section/...
i18n
路径参数结束时与
/section/
关联,这意味着在
$routeParams
服务上,
$routeParams.i18n='section'。这是意料之中的,但我需要能够解析
/:i18n/
参数,以避免这种冲突,并更改URL,连接一个区域设置,以上下文化会话,将当前路由替换为新路由,i18n化,而无需自动、有选择地刷新视图/应用程序,因为有些功能只需要更改,而不是全部

此外,我还设计了一个服务,根据可能的语言设置列表及其权重,评估将被选择到当前上下文中的语言:

var criteria = {
    default: {
        tag: 'en',
        weight: 10
    },
    user: {
        tag: 'pt',
        weight: 20
    },
    cookie: {
        tag: 'zh',
        weight: 30
    },
    url: {
        tag: 'ru',
        weight: 40
    },
    runtime: {
        tag: 'es',
        weight: 50
    }
};

function chooseLanguage (languages) {
    var deferred = $q.defer();
    var weights = [];
    var competitors = {};
    var choosen = null;

    if (defineType(languages) === 'array') {
        for (var i = languages.length - 1; i >= 0; i--) {
            if (languages[i].tag !== null) {
                weights.push(languages[i].weight);

                competitors[languages[i].weight] = languages[i];
            }
        }

        choosen = competitors[Math.max.apply(Math, weights)];
    } else if (defineType(languages) === 'object') {
        choosen = languages;
    } else {
        return;
    }

    setRuntimeLanguage(choosen.tag);

    deferred.resolve(choosen);

    return deferred.promise;
}
在解释上面的代码时,当angular引导应用程序时,将执行代码段,选择定义的语言以及其强度是否足以被选择。其他方法与此操作相关,如取消检测URL参数(如果有一个已登录的用户)等,并且此过程不仅在引导上执行,而且在多个上下文上执行:
$routeChangeStart
事件,当用户自动验证其会话时,在选择框上切换语言,等等

因此,在简历中,我需要能够:

  • 解析URL并正确应用locale参数(如果没有初始通知)
  • 在运行时更改URL
    i18n
    param,而不重新加载整个视图/应用程序
  • 正确处理语言变化,这意味着,如果我基于权重的方法不是更好的方法,如果你建议我其他方法
  • 编辑1:
    $watcher
    不起作用,因为应用程序在每个路径中都需要正确的区域设置,甚至在它实例化所有元素之前<代码>AngularJS
    用于检查的每一步,但如果在Angular实例化之前,有任何外部线索,我们可以讨论它


    目前,我正在使用下面已被接受的答案,以及我开发的解决方案,但还需要改进。

    我最终对URL进行了一种初步解析。仅使用
    ngRoute
    ui-router
    不是选项…)检查路径是否与限制匹配,如果不匹配,则触发重定向,正确定义路径

    以下是主要路线的解决方案片段,以及一个简单的后续示例,因为应用程序上的路线数量及其特定数据不属于基本想法:

    $routeProvider
        .otherwise({
            redirectTo: function () {
                return '/404/';
            }
        })
    
        .when('/:i18n/', {
            redirectPath: '/:i18n/',
            templateUrl: 'home.html',
            controller: 'HomeCtrl',
            resolve: {
                i18n: [
                    '$location',
                    '$route',
                    'i18nService',
                    function ($location, $route, i18nService) {
                        var params = $route.current.params;
    
                        return i18nService.init(params.i18n)
                            .then(null, function (fallback) {
                                if (params.i18n === '404') {
                                    return $location.path('/' + params.i18n + '/404/').search({}).replace();
                                }
    
                                $location.path('/' + fallback).search({}).replace();
                            });
                    }
                ],
                data: [
                    'dataService',
                    function (dataService) {
                        return dataService.resolve();
                    }
                ]
            }
        })
    
        .when('/:i18n/search/:search/', {
            redirectPath: '/:i18n/search/:search/',
            templateUrl: 'search.html',
            controller: 'SearchCtrl',
            resolve: {
                i18n: [
                    '$location',
                    '$route',
                    'i18nService',
                    function ($location, $route, i18nService) {
                        var params = $route.current.params;
    
                        return i18nService.init(params.i18n)
                            .then(null, function (fallback) {
                                $location.path('/' + fallback + '/search/').search({
                                    search: params.search
                                }).replace();
                            });
                    }
                ],
                data: [
                    '$route',
                    'searchService',
                    function ($route, searchService) {
                        var params = $route.current.params;
    
                        return searchService.resolve({
                            'search': params.search
                        });
                    }
                ]
            }
        });
    
    redirectPath
    属性用于您需要该路由的模式时,因为
    ngRoute
    保留一个副本供私人使用,但不允许使用
    $route
    公共属性访问它

    由于在任何应用程序请求之前都需要进行解析(除了加载区域设置列表并触发加载翻译的
    angular translate
    i18nService
    ),因此此方法会导致多次重定向,从而导致实例化的显著延迟


    如果有任何改进,我也会感谢,如果我找到了更好的方法,我会用它更新这个答案。

    你能分配一个$watcher来检查i18n变量中的更改吗,这意味着当i18n在运行时更改时,更改会传播到整个应用程序中。您还可以使用配置块(首先运行并分配路由器的位置)和运行块(之后运行)。我将尝试定义一个监视程序,但如果我更改
    $location.path()
    ,应用程序将不会重新加载?如果我没有弄错,它不会重新加载整个应用程序,但它确实会重新加载该路由上定义的任何控制器。config/run块仅在启动时运行。