#angularjs #angular-translate
#angularjs #angular-translate
Вопрос:
Как динамически определять URL таблиц перевода с помощью $translateProvider
В настоящее время мы выполняем — [https://angular-translate.github.io/docs/#/guide/12_asynchronous-loading ](асинхронная загрузка) в одном из наших приложений.Мы следовали этому методу почти 2 года. Но прямо сейчас перед нами стоит другая задача.Мы должны определить URL нашего файла перевода на основе логики.Логика такова: если файл существует в данном, location
затем разрешите перевод через него или вернитесь к default location
.
Моя текущая среда
- версия angular-translate — 2.4.2 с angular-translate-partial-loader — 2.4.2
- версия angular — 1.5
Структура приложения
|-- mod 1
| |-- de_de.json
| |-- en_us.json
| |-- es_es.json
| `-- zh_tw.json
|-- mod 2
| |-- de_de.json
...Followed by corresponding translation files.
Структура кода:
application.js
myapp.config(['$translateProvider', '$translatePartialLoaderProvider',function ( $translateProvider, $translatePartialLoaderProvider ) {
$translateProvider.useLoader( '$translatePartialLoader', {
urlTemplate: 'i18n/{part}/{lang}.json'
} );
$translateProvider.preferredLanguage( "en_us" );
$translateProvider.fallbackLanguage( "en_us" );
}]);
........
myapp.run( function ( $rootScope, $translate, editableOptions ) {
$rootScope.$on( '$translatePartialLoaderStructureChanged', function () {
$translate.refresh();
} );
editableOptions.theme = 'bs3';
} );
controller1.js
myapp.controller1("Controller1",function($scope, ...,.., $translate, $translatePartialLoader,$rootScope) {
/*@ngInject*/
$translatePartialLoader.addPart('login');
$translatePartialLoader.addPart('home');
.......
$scope.setLanguage = function(lang) {
$translate.use(lang);
}
Пока все хорошо.Теперь мы хотим изменить логику application.js
, чтобы сгенерировать таблицу перевода, разрешающую URL.Мы должны проверить, есть ли у нас таблицы перевода для particular_part/in_particular_language
.
Ожидаемая структура и поведение
|-- mod 1
| |-- Custom
| | |-- de_de.json
| | |........followed by all custom translations for mod1 i.e, $translatePartialLoader.addPart('mod1')
| |-- en_us.json
| |-- es_es.json
| `-- zh_tw.json
|-- mod 2
| |-- de_de.json
В новой структуре у нас будет пользовательский каталог под каждым модулем, если существует файл перевода для части / модуля в пользовательском, тогда разрешайте с помощью part/Custom/lang_key.json else fall back to part/lang_key.json(as before)
Как мы можем достичь этого с помощью ng-translate
? .
Подход, который я использовал, заключается в написании пользовательского загрузчика .Но options
из $translatePartialLoader
ограничивает аргумент только lang_key, который передается $translate.use(lang_key)
.Как мы можем получить mod1
переданный $translatePartialLoader.addPart('mod1')
в out customLoader
.Мы не можем передать его, $translate.use('lang_key/mod1')
поскольку мы вызываем $translate.use('land_key')
только один раз, когда пользователь входит в систему.
Если мы сможем получить добавленный модуль из $translatePartialLoader('mod1')
вызова, переданный в наш customLoader
, то, основываясь на логике, мы сможем соответствующим образом разрешить переводы.В настоящее время я застрял на том, как получить добавленную часть в customLoader
, поскольку она загружается контроллерами (контроллер 1 ..). Есть ли способ или пользовательский сервис, который должен быть написан для получения добавленной части / модуля.. в наш customLoader
если да, можете ли вы направить меня или помочь мне с соответствующим кодом, ИЛИ нам придется изменить всю структуру приложения — если изменение структуры поможет, то какой должна быть структура?
Спасибо.
Ответ №1:
Пользовательский сервис для извлечения части или модуля, выбранного пользователем.
myapp.factory('fetchLanguagePart', function ($q, $timeout) {
/*@ngInject*/
var languageService = {};
languageService.languagePart = ['defaultmod1', 'defaultmod2']; //Translation tables from these parts are always required.
languageService.getLanguagePart = function () {
var deferred = $q.defer();
var url = purl();
var part = grabbedPart;
//Logic for part deciding.
languageService.languagePart = part;
return part;
}
return languageService;
})
Конфигурация
myapp.config(['$translateProvider', '$translatePartialLoaderProvider', function ($translateProvider, $translatePartialLoaderProvider) {
//Default language loader.
// $translateProvider.useLoader( '$translatePartialLoader', {
// urlTemplate: 'i18n/{part}/{lang}.json'
// } );
//Custom language loader for angular-translate.
$translateProvider.useLoader('customLanguageTemplateLoader', {})
$translateProvider.forceAsyncReload(true);
$translateProvider.useSanitizeValueStrategy();
}]);
CustomLoader извлекает таблицы перевода модуля по умолчанию и таблицы перевода пользовательского модуля, объединяет их и передает в angular-translate.
myapp.factory('customLanguageTemplateLoader', function ($q, $http, fetchLanguagePart, $timeout) {
/*@ngInject*/
return function (options) {
var getCustomLanguagePath = function (part) {
return 'i18n/' part '/Custom/' options.key '.json';
}
var getFallBackLanguagePath = function (part) {
return 'i18n/' part '/' options.key '.json';
}
//To fetch default part translations and then merge with custom part translations
var fetchPartTranslations = function () {
var deferred = $q.defer();
var responses;
var part = fetchLanguagePart.getLanguagePart();
var customLanguageUrl = getCustomLanguagePath(part);
var fallbackLanguageUrl = getFallBackLanguagePath(part);
$http.get(fallbackLanguageUrl).success(function (fallbackResult) {
responses = fallbackResu<
$http.get(customLanguageUrl).success(function (customResult) {
var updatedResult = angular.extend(responses, customResult);
angular.extend(responses, customResult);
deferred.resolve(responses);
}).error(function (error) {
deferred.resolve(responses);
})
})
return deferred.promise;
}
var deferred = $q.defer();
var part = fetchLanguagePart.getLanguagePart();
var customLanguageUrl = getCustomLanguagePath(part);
var fallbackLanguageUrl = getFallBackLanguagePath(part);
var responses;
//To fetch default module translation tables merge it with custom module translations and then merge the result of the two with part translations.
$http.get(getFallBackLanguagePath('home')).success(function (fallBackHome) {
responses = fallBackHome;
$http.get(getCustomLanguagePath('home')).success(function (customHomeResult) {
var updatedResult = angular.extend(responses, customHomeResult);
fetchPartTranslations().then(function (partTranslations) {
angular.extend(responses, partTranslations);
angular.extend(responses, customHomeResult);
deferred.resolve(responses);
});
}).error(function (error) {
fetchPartTranslations().then(function (partTranslations) {
angular.extend(responses, partTranslations);
deferred.resolve(responses);
});
})
})
return deferred.promise;
}
})