问题描述
我看过一些 Angular 的 i18n 插件,但我不想重新发明轮子.i18next 是一个很好的库,所以我打算使用它.
I have seen some i18n plugins for Angular but I don't want to re-invent the wheel. i18next is a good library and so, I intend to use it.
我创建了一个指令 i18n,它只调用 i18n 库:
I have created a directive i18n which just calls i18n library:
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();
}
});
};
});
});
在我的页面上,我可以即时更改语言:
On my page, I can change language on the fly:
<a ng-repeat="l in languages"> <img ng-src="images/{{l.id}}.png" title="{{l.label}}" ng-click="setLanguage(l.id)" /> </a>
现在,我的主控制器定义在 html 标签上:
Now, my main controller defined on html tag:
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 指令的模板并在稍后呈现).
How it works: watcher on language initialize i18n object with new locale and then update all DOM using i18n jquery extension. Outside of this special event, my directive just does the work perfectly for all other tasks (templates using i18n directive and rendered at a later moment).
虽然它工作正常,但我知道我不应该在控制器内操作 DOM,但由于最后什么也没发生,我还没有找到更好的解决方案.
While it is working fine, I know I shouldn't manipulate DOM inside a controller but since nothing happens in the end, I haven't found a better solution.
理想情况下,我希望 Angular 重新编译所有 DOM,解析所有指令以更新标签,但我不知道该怎么做.我试过 $scope.$apply() :不工作,因为此时已经在摘要中我使用 Scope.onReady 插件没有更好的结果.
Ideally, I want Angular to re-compile all DOM, parsing all directives to update labels but I can't figure how to do it.I have tried $scope.$apply() : not working because already in digest at this pointI have used Scope.onReady plugin without better results.
显然,我对 Angular 还很陌生,我很难准确理解它是如何工作的.
Obviously, I'm very new to Angular and it's quite difficult for me to understand exactly how things work.
推荐答案
据我所知,最好不要使用 jQuery,因为它不是必需的.您可以在没有 jQuery 的情况下使用 i18next,只需使用 window.i18n.t("YourStringToTranslate")
.;)
As far as I can say, it is better not to use jQuery at all, since it isn't required. You can use i18next without jQuery, by simply using window.i18n.t("YourStringToTranslate")
. ;)
因为您可以编写自己的指令,所以您也不需要使用 $(document).i18n();
.为此,我为 Angular 编写了一个简单的指令.
Because you can write your own directive you also do not need to use $(document).i18n();
.For that purpose I have written a simple directive for Angular.
https://gist.github.com/archer96/5239617
如您所见,您不必使用 jQuery,而且您最好在指令中而不是控制器中初始化 i18next.
As you can see, you don't have to use jQuery and you also better initialize i18next in your directive instead of your controller.
您可以通过 simlpy 向您想要的任何元素添加 ng-i18next=""
属性来使用它.将您的选项传递给代码中任何位置的 $rootScope.i18nextOptions
(例如在您的控制器中).然后它会自动更新所有已翻译的元素.
You can use it by simlpy adding a ng-i18next=""
attribute to any element you want.Pass your options to $rootScope.i18nextOptions
anywhere in your code (for example in your controller). It then will automatically update all translated elements.
我编辑了你的代码,所以它适用于我的指令.
I edited your code, so it works with my directive.
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 中找到它们.;)
Please note that you have to set the directive as a dependence of your app. Also include the i18next version without AMD+jQuery.If you need more details, they are available in the gist. ;)
现在在 GitHub 上提供了一个 i18next
angular
模块:https://github.com/i18next/ng-i18next
There is now an i18next
angular
module available on GitHub: https://github.com/i18next/ng-i18next
这篇关于AngularJS 和 i18next的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!