5

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

私のページでは、その場で言語を変更できます。

<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 オブジェクトを新しいロケールで初期化し、i18n jquery 拡張機能を使用してすべての DOM を更新します。この特別なイベント以外では、私のディレクティブは他のすべてのタスク (i18n ディレクティブを使用し、後でレンダリングされるテンプレート) に対して完全に機能します。

正常に動作している間は、コントローラー内で DOM を操作すべきではないことはわかっていますが、最終的には何も起こらないため、より良い解決策が見つかりませんでした。

理想的には、Angular ですべての DOM を再コンパイルし、すべてのディレクティブを解析してラベルを更新するようにしたいのですが、その方法がわかりません。私は試しました $scope.$apply() : この時点で既にダイジェストにあるため、動作しません Scope.onReady プラグインを使用しましたが、より良い結果は得られませんでした。

明らかに、私はAngularに非常に慣れていないため、物事がどのように機能するかを正確に理解することは非常に困難です.

4

1 に答える 1

7

私が言える限りでは、jQuery は必須ではないので、まったく使用しない方がよいと言えます。を使用するだけで、jQuery なしで i18next を使用できます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;
      };

  }]);
});

アプリの依存関係としてディレクティブを設定する必要があることに注意してください。AMD+jQuery を使用しない i18next バージョンも含めます。詳細が必要な場合は、Gist で入手できます。;)


i18next angularGitHub でモジュールを利用できるようになりました: https://github.com/i18next/ng-i18next

于 2013-03-27T11:27:37.057 に答える