Javascript 带路径参数的angularjs i18n路由
在我正在使用的一个应用程序中,路由系统需要与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/关联,这意
$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参数(如果没有初始通知)李>
在运行时更改URLi18n
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块仅在启动时运行。