Angular和i18next

Arn*_*aud 5 javascript internationalization angularjs angularjs-directive

我见过Angular的一些i18n插件,但我不想重新发明这个轮子.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();
                }
            });
        };
    });
});
Run Code Online (Sandbox Code Playgroud)

在我的页面上,我可以动态更改语言:

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

现在,我的主控制器在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;
        };

    }]);
});
Run Code Online (Sandbox Code Playgroud)

工作原理:语言上的观察者使用新的语言环境初始化i18n对象,然后使用i18n jquery扩展名更新所有DOM.在这个特殊事件之外,我的指令只对所有其他任务完成了工作(模板使用i18n指令并在以后呈现).

虽然它工作正常,但我知道我不应该在控制器内部操纵DOM,但由于最终没有任何反应,我还没有找到更好的解决方案.

理想情况下,我希望Angular重新编译所有DOM,解析所有指令以更新标签,但我无法弄清楚如何做到这一点.我已经尝试了$ scope.$ apply():没有工作因为已经在摘要中我已经使用了Scope.onReady插件而没有更好的结果.

显然,我对Angular很新,我很难理解事情是如何运作的.

And*_*M96 7

据我所知,最好不要使用jQuery,因为它不是必需的.您只需使用即可在不使用jQuery的情况下使用i18next window.i18n.t("YourStringToTranslate").;)

因为您可以编写自己的指令,所以也不需要使用$(document).i18n();.为此,我为Angular编写了一个简单的指令.

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

如您所见,您不必使用jQuery,也可以在指令而不是控制器中更好地初始化i18next.

你可以通过simlpy将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;
      };

  }]);
});
Run Code Online (Sandbox Code Playgroud)

请注意,您必须将指令设置为您的应用程序的依赖项.还包括没有AMD + jQuery的i18next版本.如果您需要更多细节,可以在要点中找到它们.;)


现在i18next angularGitHub上有一个模块:https://github.com/i18next/ng-i18next