[英]AngularJS and i18next
我見過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很新,我很難理解事情是如何運作的。
據我所知,最好不要使用jQuery,因為它不是必需的。 只需使用window.i18n.t("YourStringToTranslate")
,就可以在沒有jQuery的情況下使用i18next。 ;)
因為你可以編寫自己的指令,所以你也不需要使用$(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;
};
}]);
});
請注意,您必須將指令設置為您的應用程序的依賴項。 還包括沒有AMD + jQuery的i18next版本。 如果您需要更多細節,可以在要點中找到它們。 ;)
現在GitHub上有一個i18next
angular
模塊: https : //github.com/i18next/ng-i18next
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.