5

Я видел некоторые плагины i18n для Angular, но я не хочу заново изобретать колесо. i18next - хорошая библиотека, и поэтому я намерен ее использовать.Угловые и i18next

Я создал директиву i18n, которая просто вызывает i18n библиотека:

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(); 
       } 
      }); 
     }; 
    }); 
}); 

На моей странице, я могу изменить язык на лету:

<a ng-repeat="l in languages"> <img ng-src="images/{{l.id}}.png" title="{{l.label}}" ng-click="setLanguage(l.id)" /> </a> 

Теперь мой главный контроллер, определенный на HTML тег:

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; 
     }; 

    }]); 
}); 

Как это работает: наблюдатель на языке инициализирует объект i18n с новым языком и d затем обновите все DOM, используя расширение iQn jquery. Вне этого специального события моя директива просто отлично работает для всех других задач (шаблоны с использованием директивы i18n и отображаются позже).

Хотя он работает нормально, я знаю, что я не должен манипулировать DOM внутри контроллера, но поскольку в конце ничего не происходит, я не нашел лучшего решения.

В идеале, я хочу, чтобы угловое преобразование всех DOM, разбор всех директив для обновления меток, но я не могу понять, как это сделать. Я пробовал $ scope. $ Apply(): не работает, потому что уже в дайджесте на данный момент Я использовал плагин Scope.onReady без лучших результатов.

Очевидно, что я очень новичок в Angular, и мне очень сложно понять, как все работает.

ответ

7

Насколько я могу судить, лучше не использовать jQuery вообще, так как это не требуется. Вы можете использовать i18next без jQuery, просто используя window.i18n.t("YourStringToTranslate"). ;)

Поскольку вы можете написать свою собственную директиву, вам также не нужно использовать $(document).i18n();. Для этого я написал простую директиву для Angular.

https://gist.github.com/archer96/5239617

Как вы можете видеть, вы не должны использовать JQuery и вы также лучше инициализировать i18next в вместо вашей директивы контроллера.

Вы можете использовать его, просто добавив атрибут ng-i18next="" к любому элементу, который вы хотите. Передайте свои варианты $rootScope.i18nextOptions в любом месте вашего кода (например, в вашем контроллере). Затем он автоматически обновит все переведенные элементы.

Я отредактировал ваш код, поэтому он работает с моей директивой.

define(['app', 'i18n', 'jquery'], function(app, i18n, $) { 

    'use strict'; 

    return app.controller('BuilderController', ['$rootScope', '$scope', '$location', 
    function BuilderController($rootScope, $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" 
     }]; 

     // This has changed 
     $scope.$watch('language', function() { 
     $location.search('lang', $scope.language); 
     $rootScope.i18nextOptions = { 
      resGetPath : 'i18n/__lng__/__ns__.json', 
      lng : $scope.language, 
      getAsync : false, 
      sendMissing : true, 
      fallbackLng : 'en', 
      debug : true 
     }; 
     }); 

     $scope.setLanguage = function(id) { 
      $scope.language = id; 
     }; 

    }]); 
}); 

Обратите внимание, что вы должны установить директиву в зависимости от вашего приложения. Также включите версию i18next без AMD + jQuery. Если вам нужна дополнительная информация, они доступны в тексте.;)


Существует в настоящее время i18nextangular модуль доступен на GitHub: https://github.com/i18next/ng-i18next

Смежные вопросы