Now translations are just "view logic". It doesn't change anything in the underlying data. It's like a "face" of an Xbox controller. No matter how many faces you have, you may even have them cataloged alphabetically, you'll always have the buttons, sticks and triggers working in the same way.
So let's apply the same concept to Angular. The only thing your controller should be aware about is the data. As for how we will know what text to put in to the UI, we represent the text as "keys". These will correspond to text defined somewhere in Angular, like a Factoryconstant. Where the key and your translation meet is the UI, via filters.
controller -(key, data)-> UI -------(key)-------> filter
filter <-(current language)- service
filter <-(translation key)- constant
UI <-(translated text)- filter
// Sample translation key
app.constant('Translations', {
en: {
'PAGE_TITLE': 'Hi',
},
es: {
'PAGE_TITLE': 'Hola!',
}
});
// Sample factory which only holds our current language state
app.factory('LanguageService', function(){
var currentLanguage = 'en';
return {
setCurrentLanguage: function(value){
currentLanguage = value;
},
getCurrentLanguage: function(){
return currentLanguage;
}
}
});
// Sample filter which transforms our UI value
app.filter('translate', function(Translations, LanguageService){
// We receive the input, translate according to the current language and key
// and return the output.
return function(input){
// Translations.en.PAGE_TITLE
return Translations[LanguageService.getCurrentLanguage()][input] || '';
};
});
// Sample controller
app.controller('MyController', function(LanguageService){
$scope.data = {
// Note that it only holds the "key" to the text. The filter will figure it
// out for you. This data will be the same across all languages.
title: 'PAGE_TITLE',
url: '/home',
};
// The only time your controller is
$scope.changeLanguage = function(value){
LanguageService.setCurrentLanguage(value);
};
});
// Sample UI
<!-- This passes title to the translate, then renders the return value -->
<div><a href="{{ url }}">{{ title | translate }}</div>a>
<button type="button" ng-click="setCurrentLanguage('en')>English</button>
<button type="button" ng-click="setCurrentLanguage('es')>Español</button>
As you can see, the UI isn't aware of language-specific stuff. The only thing it knows is that there's a title and URL. Any language-specific things should be represented as keys in the data, in this case title. Since url remains the same, we can simply render it in the UI straight away.
The only inconvenience I see is that your data should carry keys instead of text, and that it should correspond to the keys found in the constants.