Last active
August 29, 2015 14:07
-
-
Save RodolpheGohard/3a7a4bfc9e3d3ed56988 to your computer and use it in GitHub Desktop.
My a-bit-hacky implementation for automatic partial loading with angular-translate.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
//NB: parts have been stripped to improve readability | |
var l10nModule = angular.module( 'tnbl10n', [ | |
'ngResource', | |
'sessionstatus' //This is a module we use here to get the language in use | |
] ); | |
//Backend link | |
l10nModule.factory('TranslationWebService', function($resource, sessionStatus) { | |
return $resource('api/i18n/translations-' + sessionStatus.lang); | |
}); | |
l10nModule.config( function ( $translateProvider ) { | |
$translateProvider.useMissingTranslationHandler( 'myCustomHandlerFactory' ); | |
$translateProvider.useLoader('customLoader'); | |
$translateProvider.determinePreferredLanguage(); | |
//$translateProvider.preferredLanguage('en'); | |
$translateProvider.usePostCompiling(true); | |
} ); | |
l10nModule.value( 'translations', { | |
fr : { | |
unresolvedTranslations: {}, | |
queuedTranslations: {}, | |
requestedTranslations: {}, | |
loadedTranslatations: {} | |
}, | |
en : { | |
//Keeps missing translations which hasn't been loaded yet | |
unresolvedTranslations: {}, | |
//missing translations for which a server request has been sent and we're waiting for | |
queuedTranslations: {}, | |
//missing translations for which a server request has been sent (from the beginning) | |
//this is useful when a translation doesn't exist, so the system doesn't loop requesting for it | |
requestedTranslations: {}, | |
//translatations successfully loaded | |
loadedTranslatations: {} | |
} | |
} ); | |
l10nModule.factory( 'myCustomHandlerFactory', function ( $translate, customLoader, translations, sessionStatus ) { | |
// has to return a function which gets a tranlation ID | |
return function ( translationID , lang) { | |
if(!lang){ | |
lang = sessionStatus.lang; | |
} | |
translations[lang].unresolvedTranslations[translationID] = true; | |
//The translation doesn't exist, just print its ID | |
if ( translations[lang].requestedTranslations[translationID] ) return translationID; | |
if ( translations[lang].queuedTranslations[translationID] ) return; | |
//The translation has to be loaded, in the meantime, we show '...' | |
//which is a clue for the user that content is being loaded | |
customLoader.requireRefresh(translationID); | |
return '...'; | |
}; | |
} ); | |
l10nModule.factory('customLoader', function ( $resource, $http, $q, $log, $translate, $locale, _, translations) { | |
// return loaderFn | |
var customLoader = function (options) { | |
var deferred = $q.defer(); | |
// do something with $http, $q and key to load localization files | |
$log.log( 'there customLoader:', options ); | |
var lang = options.key; | |
var url = 'api/i18n/partialtranslations-:locale'; | |
//We extract groups from all missing translations | |
var groups = _.uniq(_.keys( translations[lang].unresolvedTranslations ).map(function(key) { | |
return key.split('.')[0]; | |
})).join(); | |
// Do not send empty requests, possible infinite loops | |
if(!groups.length) deferred.resolve(options.key) | |
else | |
$resource(url,{locale:lang}).get( | |
{ | |
groups: groups | |
}, | |
function(jsonResponse, status, headers, config) { | |
//if we just resolved jsonResponse.data here, previously loaded translations would be lost. | |
angular.extend( translations[lang].loadedTranslatations, jsonResponse.data ); | |
deferred.resolve(translations[lang].loadedTranslatations); | |
}, | |
function(jsonResponse, status, headers, config) { | |
//NOTE: angular-translation is buggy if we reject here. He will stop triggering the missing translation handler ever after | |
deferred.resolve(options.key); | |
} | |
); | |
translations[lang].queuedTranslations = translations[lang].unresolvedTranslations; | |
angular.extend( translations[lang].requestedTranslations, translations[lang].unresolvedTranslations ); | |
translations[lang].unresolvedTranslations = {}; | |
return deferred.promise; | |
}; | |
var LOADER_DEBOUNCE_DELAY = 100; | |
var debouncedRequireRefresh = _.debounce( function() { | |
$translate.refresh(); | |
} , LOADER_DEBOUNCE_DELAY); | |
customLoader.requireRefresh = function() { | |
debouncedRequireRefresh(); | |
}; | |
return customLoader; | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment