我正在使用出色的 Angular Translate ($translate
) 指令/服务来处理多种语言环境,因为我有多个语言环境文件,所以我使用方便的 $translateProvider.useStaticFilesLoader
通过 localeAbbr.json 的结构加载我的翻译文件,例如 en.json
,es.json
等...我构建了一个 Plunker 来展示我的开源项目,该项目通过 Git 原始文件使用语言环境(指向实际的 Github 存储库,这意味着不是 plunker 演示的本地)。我的项目是作为一个指令和一个服务构建的,我制作了一个小的 Plunker 来显示我的 JSON 文件加载的时间问题。
综上所述,$translateProvider.useStaticFilesLoader
似乎可以异步
,而我真的需要它是同步
,因为到时候plunker 运行,JSON 文件尚未解析,而我已经在我的消息上调用了 $translate.instant()
。
我有一个 Plunker显示问题。
这是我的快速服务演示的一部分:
app.factory('validationService', ['$filter', '$translate', function ($filter, $translate) {
var service = this;
var validationSummary = [];
var errorMessages = [
'INVALID_ALPHA',
'INVALID_ALPHA_SPACE',
'INVALID_ALPHA_NUM',
'INVALID_BOOLEAN'
];
//var $translate = $filter('translate');
for(var i=0, ln=errorMessages.length; i < ln; i++) {
validationSummary.push({
field: i,
message: $translate.instant(errorMessages[i])
});
}
// attach public functions
service.getValidationSummary = getValidationSummary;
return service;
// function declaration
function getValidationSummary() {
return validationSummary;
}
}]);
$translateProvider 配置
app.config(['$translateProvider', function ($translateProvider) {
$translateProvider.useStaticFilesLoader({
prefix: 'https://rawgit.com/ghiscoding/angular-validation/master/locales/validation/',
suffix: '.json'
});
// load English ('en') table on startup
$translateProvider.preferredLanguage('en').fallbackLanguage('en');
}]);
通过 Controller 调用我的服务:
app.controller("TestController", function($scope, validationService) {
var vm = this;
vm.displayValidationSummary = true;
vm.validationSummary = validationService.getValidationSummary();
});
最后是使用 Controller 的 HTML:
<div class="alert alert-danger alert-dismissable" ng-show="vm.displayValidationSummary">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true" ng-click="displayValidationSummary = false">×</button>
<h4><strong>{{ 'ERRORS' | translate }}!</strong></h4>
<ul>
<li ng-repeat="item in vm.validationSummary">{{item.field }}: {{item.message}}</li>
</ul>
</div>
由于我使用的是 AngularJS 1.3+,我还发现 $translate
只被翻译一次,所以作者建议使用 translateFilter.$stateful = true;
我试过了,但这似乎没有帮助。
这里又是Plunker
我花了数周时间尝试寻找和编写各种解决方案,但我从来没有让它工作,看到我的原始翻译代码我真的很难过:(
请帮忙!!!
编辑
我意识到我的问题并没有涵盖与我的问题相关的所有内容。除了翻译延迟问题之外,我还必须传递额外的参数,这是将它们传递给翻译匿名函数的一个大问题。到 promise 完成时,我的论证状态已经改变。例如:
$translate(validator.message).then(function(translation) {
// only log the invalid message in the $validationSummary
addToValidationSummary(formElmObj, translation);
// error Display
if(!isValid) {
updateErrorMsg(translation, isValid);
}else if(!!formElmObj && formElmObj.isValid) {
addToValidationSummary(formElmObj, '');
}
}, function(data) {
throw 'Failed to translate' + data;
});
最佳答案
在使用 AngularJS 或 JavaScript 时,您确实需要接受异步范例。为了减少处理异步代码的麻烦,您可以使用 Promises。 Angular 为您提供了一项名为 $q 的服务,它可以为您完成繁重的工作
https://docs.angularjs.org/api/ng/service/$q
让人们思考 Promises 可能需要时间,但从长远来看非常值得付出努力。
本质上,您需要对 validationService 执行的操作是使用 $translate 的 promise api,它将根据提供的 key 为您提供所需的翻译。这归结为你向 $translate 请求所有你希望获得翻译的 translationId,当所有的都被获取后,你用你的消息填充 validationSummary 数组。
app.factory('validationService', ['$q', '$translate', function ($q, $translate) {
var translationsPromises = [],
validationSummary = [],
errorMessages = [
'INVALID_ALPHA',
'INVALID_ALPHA_SPACE',
'INVALID_ALPHA_NUM',
'INVALID_BOOLEAN'
];
angular.forEach(errorMessages, function(val, key) {
translationsPromises.push($translate(val));
});
$q.all(translationsPromises)
.then(function(translations) {
angular.forEach(translations, function(val, key) {
validationSummary.push({
filed: key,
message: val
});
});
})
.catch(function (err) {
console.error('Failed to translate error messages for validation summary', err);
});
// function declaration
function getValidationSummary() {
return validationSummary;
}
return {
getValidationSummary: getValidationSummary
};
}]);
我已经 fork 你的 plunker 并修改它以包含上面的示例
http://plnkr.co/edit/7DCwvY9jloXwfetKtcDA?p=preview
另一个观察结果是您在 HTML 中使用了翻译过滤器。请注意,如果你有一个大的 DOM,这可能会被证明是昂贵的,因为 Angular 会调用翻译每个摘要上的每个键。一种可以考虑的方法是为您的虚拟机提供一个标签对象,并使用 $filter 服务在 Controller 实例化时填充它们。
关于javascript - $translateProvider.useStaticFilesLoader 的 Angular Translate 异步计时问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29551379/