Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Further research</strong></p> <p>Here is my App:</p> <pre><code>'use strict'; var myApp = angular.module('myApp', []); </code></pre> <p>Here is my controller:</p> <pre><code>'use strict'; myApp.controller('PageController', function PageController($scope, translationService, $rootScope) { $rootScope.currentLanguage = 'en'; $rootScope.translations = translationService.getTranslations($scope.currentLanguage); $scope.setLanguage = function(language) { if (language === $scope.currentLanguage) { return; } $rootScope.currentLanguage = language; $rootScope.translations = translationService.getTranslations($scope.currentLanguage); } } ); </code></pre> <p>And here is the translationService:</p> <pre><code>'use strict'; myApp.service('translationService', function ($http, $q) { var translationsCache = {}; return { getTranslations: function(language) { if (translationsCache[language]) { return translationsCache[language]; } var deferred = $q.defer(); // **** FAKE SOLUTION **** // // I just return a resolve here as it doesn't really matter for this test. if (language == 'sv') { deferred.resolve({ "My first text unit": "Detta är min första text unit", "I am a Pirate": "Jag är en Pirat" }); } else if (language == 'en') { deferred.resolve({ "My first text unit": "This is my first Text unit", "I am a Pirate": "I'm a Pirate" }); } translationsCache[language] = deferred.promise; return deferred.promise; // **** END FAKE SOLUTION **** // /* // **** WORKING SOLUTION **** // The probable real solution to fetching language JSON generated by Symfony somewhere $http({method: 'GET', url: '/translations/'+language}). success(function (data, status, headers, config) { deferred.resolve(data); }). error(function(data, status, headers, config) { deferred.reject(status); }); translationsCache[language] = deferred.promise; return deferred.promise; // **** END WORKING SOLUTION **** // */ } } }); </code></pre> <p>So here is my directive that I came up with after some trial and error:</p> <pre><code>myApp.directive('translation', function($rootScope) { return { restrict: 'A', // Restrict to attribute replace: true, // Replace current object by default, not for input though, see solution below link: function(scope, element, attrs, controller){ // This will watch for changes in currentLanguage in your $rootScope scope.$watch(function() { return $rootScope.currentLanguage; // If this changes then trigger function (binding) }, function(newVal, oldVal) { // As we have translation as a promise this is how we do $rootScope.translations.then(function(translations) { // Does it exist, then translate it, otherwise use default as fallback if (translations[scope.translation]) { // Just some extra I found could be useful, set value if it is a button or submit. Could be extended. if (element.prop('tagName') === 'INPUT' &amp;&amp; (element.prop('type') === 'button' || element.prop('type') === 'submit')) { return angular.element(element).val(translations[scope.translation]); } // Else just change the object to be the new translation. return element.html(translations[scope.translation]); } // This is the fallback, and same as above, button and submit if (element.prop('tagName') === 'INPUT' &amp;&amp; (element.prop('type') === 'button' || element.prop('type') === 'submit')) { return element.val(scope.translation); } return element.html(scope.translation); }); }); }, scope: { translation: "@" // Save the parameter to the scope as a string } } }); </code></pre> <p>And here are some examples of how to use it.</p> <p>HTML:</p> <pre><code>&lt;div class="container"&gt; &lt;div class="nav"&gt; &lt;button ng-click="setLanguage('en')"&gt; &lt;trans translation="English" /&gt; &lt;/button&gt; &lt;button ng-click="setLanguage('sv')"&gt; &lt;trans translation="Svenska" /&gt; &lt;/button&gt; &lt;/div&gt; &lt;hr /&gt; &lt;p&gt;&lt;trans translation="I am a Pirate" /&gt;&lt;/p&gt; &lt;p&gt;&lt;trans translation="A text unit that doesn't exist" /&gt;&lt;/p&gt; &lt;p&gt;&lt;input type="button" translation="My button" /&gt;&lt;/p&gt; &lt;/div&gt; </code></pre> <p>This would work as following using the jsFiddle: <a href="http://jsfiddle.net/Oldek/95AH3/4/" rel="nofollow">http://jsfiddle.net/Oldek/95AH3/4/</a></p> <p><strong>This this solves:</strong></p> <ul> <li>Fetch translations asynchronously</li> <li>Cache translations so switch is really fast</li> <li>Working with input / fields with value</li> <li>Store language in Local Storage</li> <li>Dynamically update the whole DOM on translation change</li> <li>Really quick, at least the scale I have tried</li> <li>Full and working solution to a common problem</li> </ul> <p><strong>Things to solve:</strong></p> <ul> <li>Move out code that checks if it is an input field somewhere else</li> <li>Pluralisation</li> <li>Input Placeholder</li> <li>And other features a translation supports.</li> <li>Support parameters, see example:</li> </ul> <p><code>&lt;trans translation="Hello {{name}}" name="{{name}}"&gt;</code></p> <ul> <li>Scan the project with xgettext? and generate an YML or similar structure that can be translated in some software.</li> <li>Remove the temporary solution and use the working one commented out.</li> </ul> <p><strong>Other Comments</strong></p> <p>Please feel free to ask questions if you have, I'll provide info, and probably a jsFiddle some time soon in deemed needed.</p> <p>/Marcus</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload