Я использую отличную директиву/службу Angular Translate ($translate
) для работы с несколькими языками локали, и, поскольку у меня есть несколько файлов локалей, я использую удобный $translateProvider.useStaticFilesLoader
для загрузки файлов перевода через структуру localeAbbr.json, например en.json
, es.json
, и т. д. Я создал плункер, чтобы показать свой проект с открытым исходным кодом, и этот проект использует локаль через необработанные файлы Git (указывая на фактический репозиторий Github, что означает, что он не является локальным для демонстрации плунжера). Мой проект построен как директива и служба, я сделал небольшой плункер, чтобы показать мою проблему с синхронизацией при загрузке файла JSON.
Все это говорит о том, что кажется, что $translateProvider.useStaticFilesLoader
работает asynchronous
, в то время как мне действительно нужно, чтобы это было synchronous
, потому что к тому времени, когда плункер запускается, файлы 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');
}]);
Вызовите мою службу через контроллер:
app.controller("TestController", function($scope, validationService) {
var vm = this;
vm.displayValidationSummary = true;
vm.validationSummary = validationService.getValidationSummary();
});
и, наконец, 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
Я потратил недели, пытаясь найти и закодировать все виды решений, но у меня так и не получилось, и мне очень грустно видеть мой необработанный код перевода :(
Пожалуйста помоги!!!
EDIT
Я понял, что мой вопрос не охватывает все, что связано с моей проблемой. Помимо проблемы с задержкой перевода, мне также приходится передавать дополнительные аргументы, и это огромная проблема с их передачей анонимной функции перевода. К тому времени, когда обещание закончено, состояние моих аргументов уже изменилось. Например:
$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;
});