问题描述
我已经看到了一些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,因为它不是必需的.只需使用window.i18n.t("YourStringToTranslate")
,就可以在不使用jQuery的情况下使用i18next. ;)
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.
您可以通过简单地将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版本.如果您需要更多详细信息,请在要点中找到它们. ;)
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!