title: AngularJS and i18next
body: <p>I have seen some i18n plugins for Angular but I don't want to re-invent the wheel. i18next is a good library and so, I intend to use it.</p>
  
  <p>I have created a directive i18n which just calls i18n library:</p>
  
  <pre><code>define(['app', 'jquery', 'i18n'], function(app, $, i18n) {'use strict';
      app.directive('i18n', function() {
          return function($scope, elm, attrs) {
              attrs.$observe('i18n', function(value) {
                  if ($.fn.i18n) {// for some reason, it isn't loaded quickly enough and first directives process fails
                      $(elm).i18n();
                  }
              });
          };
      });
  });
  </code></pre>
  
  <p>On my page, I can change language on the fly:</p>
  
  <pre><code>&lt;a ng-repeat="l in languages"&gt; &lt;img ng-src="images/{{l.id}}.png" title="{{l.label}}" ng-click="setLanguage(l.id)" /&gt; &lt;/a&gt;
  </code></pre>
  
  <p>Now, my main controller defined on html tag:</p>
  
  <pre><code>define(['app', 'i18n', 'jquery'], function(app, i18n, $) {'use strict';
  
      return app.controller('BuilderController', ['$scope', '$location',
      function BuilderController($scope, $location) {
  
          /* Catch url changes */
          $scope.$watch(function() {
              return $location.path();
          }, function() {
              $scope.setLanguage(($location.search()).lang || 'en');
          });
  
          /* Language */
          $scope.languages = [{
              id : "en",
              label : "English"
          }, {
              id : "fr",
              label : "Français"
          }];
  
          $scope.$watch('language', function() {
              $location.search('lang', $scope.language);
              i18n.init({
                  resGetPath : 'i18n/__lng__/__ns__.json',
                  lng : $scope.language,
                  getAsync : false,
                  sendMissing : true,
                  fallbackLng : 'en',
                  debug : true
              });
              $(document).i18n();
          });
  
          $scope.setLanguage = function(id) {
              $scope.language = id;
          };
  
      }]);
  });
  </code></pre>
  
  <p>How it works: watcher on language initialize i18n object with new locale and then update all DOM using i18n jquery extension. Outside of this special event, my directive just does the work perfectly for all other tasks (templates using i18n directive and rendered at a later moment).</p>
  
  <p>While it is working fine, I know I shouldn't manipulate DOM inside a controller but since nothing happens in the end, I haven't found a better solution.</p>
  
  <p>Ideally, I want Angular to re-compile all DOM, parsing all directives to update labels but I can't figure how to do it.
  I have tried $scope.$apply() : not working because already in digest at this point
  I have used Scope.onReady plugin without better results.</p>
  
  <p>Obviously, I'm very new to Angular and it's quite difficult for me to understand exactly how things work.</p>