Skip to content

Instantly share code, notes, and snippets.

@RodolpheGohard
Last active August 29, 2015 14:07
Show Gist options
  • Save RodolpheGohard/3a7a4bfc9e3d3ed56988 to your computer and use it in GitHub Desktop.
Save RodolpheGohard/3a7a4bfc9e3d3ed56988 to your computer and use it in GitHub Desktop.
My a-bit-hacky implementation for automatic partial loading with angular-translate.
(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