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に非常に慣れていないため、物事がどのように機能するかを正確に理解することは非常に困難です.