问题描述
以下是英语的 json i18n 语言文件示例:
{项目": {赞助商信息":{"MAIN" : "选择赞助商名称",赞助商":[{"赞助商":"赞助商名称 1" },{赞助商":赞助商名称2"}]}}}
这是我的 html 视图:
<label for="form-field-select-1" translate="project.SPONSORINFO.MAIN">标签><select class="form-control" ng-model="myModel.sponsors"><option ng-repeat="s in projectJSON.project.SPONSORINFO.SPONSORLIST" value="{{s.spons}}">{{s.spons |翻译}}</option></选择>
标签中的translate="project.SPONSORINFO.MAIN"
正确显示值选择赞助商名称"当语言切换被点击时(不需要刷新).
问题:
我在视图控制器中使用以下函数根据所选语言加载语言文件并将其传递到 $scope.projectJSON
以便我可以在 ng- 中调用它在我的 html 视图中重复
:
var lang = $translate.use();$http.get('assets/i18n/'+lang+'.json').success(function(data) {$scope.projectJSON=数据;});
问题是切换语言后,下拉菜单不会更改为所选语言,除非我刷新或更改视图并返回.如何解决此问题,使其像标签一样工作?
附件:
在我的 main.js 中翻译全局配置,如下所示:
app.config(['$translateProvider',函数($translateProvider){//需要前缀和后缀信息来指定模式//您可以简单地使用具有此模式的静态文件加载器:$translateProvider.useStaticFilesLoader({前缀:'assets/i18n/',后缀:'.json'});//由于您现在已经注册了不止一个转换表,angular-translate 必须知道使用哪一个.//这就是 preferredLanguage(langKey) 的用武之地.$translateProvider.preferredLanguage('en');//将语言存储在本地存储中$translateProvider.useLocalStorage();}]);
我的mainCtrl.js
中的翻译配置:
app.controller('AppCtrl', ['$rootScope', '$scope', '$state', '$translate',函数($rootScope,$scope,$state,$translate){$scope.language = {//处理语言下拉菜单listIsOpen: 假,//可用语言列表可用的: {'en': '英语',//'it_IT': '意大利语','de_DE': '德语'},//始终显示当前的 ui 语言初始化:函数(){var 提议的语言 = $translate.proposedLanguage() ||$translate.use();var preferredLanguage = $translate.preferredLanguage();//我们知道我们在 app.config 中设置了首选$scope.language.selected = $scope.language.available[(proposedLanguage || preferredLanguage)];},设置:函数(localeId,ev){$translate.use(localeId);$scope.language.selected = $scope.language.available[localeId];$scope.language.listIsOpen = !$scope.language.listIsOpen;}};$scope.language.init();
您正在从翻译 json 文件迭代数组.此翻译 json 文件由 $translate
服务加载,您将无法访问已加载的内容,但您需要此 json 文件中的数据对其进行迭代,因此您必须发出自己的请求才能获取这个数组.也许你不想,但你必须进行 $http.get
调用.
在您的代码中,通过执行这一行 var lang = $translate.use(newLang);
发出一个请求,第二个调用由 $http.get
完成,但是如果 $http.get
在调用 $translate.use
之前被解析它不会翻译下拉列表中的内容,因为 $translate.use
尚未解析,$translate
服务没有这些翻译要翻译.
你可以做的是在 $rootScope
上监听 $translateChangeSuccess
事件(由 $translate
服务发出),然后让你的 ajax在这个处理程序中调用.
我已经在您的示例中测试了以下代码,并且运行良好.
[更新]
$rootScope.$on('$translateChangeSuccess', function () {//获取新的当前新语言var lang = $translate.use();$http.get('assets/i18n/'+lang+'.json').success(function(data) {$scope.projectJSON = 数据;});});
有关角度翻译模块事件部分的详细说明,请查看此链接.
每当你调用 $translate.use(localeId)
时,它会在内部进行 ajax 调用,当这个调用被解决时,它会发出 $translateChangeSuccess
事件,然后你让你的请求、加载数据和更新$scope.projectJSON
.
唯一的事情是第一次触发这个事件,当你刷新浏览器时,当 $translate.use
没有被调用.
为此,您只需在页面重新加载时调用一次 $translate.use
.
[更新]
将以下代码放在 $scope.language.init
函数的末尾.
$translate.use(proposedLanguage || preferredLanguage);
这应该可以解决您的问题.
Here is an example json i18n language file for English:
{
"project": {
"SPONSORINFO": {
"MAIN" : "Select the Sponsor Name",
"SPONSORLIST": [
{"spons" :"SponsorName 1" },
{"spons" :"SponsorName 2" }
]
}
}
}
and here is my html view:
<div class="form-group" >
<label for="form-field-select-1" translate="project.SPONSORINFO.MAIN">
</label>
<select class="form-control" ng-model="myModel.sponsors">
<option ng-repeat="s in projectJSON.project.SPONSORINFO.SPONSORLIST" value="{{s.spons}}">{{s.spons | translate}}</option>
</select>
</div>
The translate="project.SPONSORINFO.MAIN"
in the label is rightly showing the value "Select the Sponsor Name" as soon as the language toggle is clicked (no refresh is needed).
Question:
I am using the following function in my view controller to load the language file based on the selected language and pass it into $scope.projectJSON
so that I can call it in ng-repeat
in my html view:
var lang = $translate.use();
$http.get('assets/i18n/'+lang+'.json').success(function(data) {
$scope.projectJSON= data;
});
The problem is that after toggling the language, the dropdown menus don't get changed to the selected language unless I refresh or change view and come back. How can I fix this issue so that it works like the label?
annex:
Translation global config in my main.js like the following:
app.config(['$translateProvider',
function ($translateProvider) {
// prefix and suffix information is required to specify a pattern
// You can simply use the static-files loader with this pattern:
$translateProvider.useStaticFilesLoader({
prefix: 'assets/i18n/',
suffix: '.json'
});
// Since you've now registered more then one translation table, angular-translate has to know which one to use.
// This is where preferredLanguage(langKey) comes in.
$translateProvider.preferredLanguage('en');
// Store the language in the local storage
$translateProvider.useLocalStorage();
}]);
translation config in my mainCtrl.js
:
app.controller('AppCtrl', ['$rootScope', '$scope', '$state', '$translate',
function ($rootScope, $scope, $state, $translate) {
$scope.language = {
// Handles language dropdown
listIsOpen: false,
// list of available languages
available: {
'en': 'English',
//'it_IT': 'Italiano',
'de_DE': 'Deutsch'
},
// display always the current ui language
init: function () {
var proposedLanguage = $translate.proposedLanguage() || $translate.use();
var preferredLanguage = $translate.preferredLanguage();
// we know we have set a preferred one in app.config
$scope.language.selected = $scope.language.available[(proposedLanguage || preferredLanguage)];
},
set: function (localeId, ev) {
$translate.use(localeId);
$scope.language.selected = $scope.language.available[localeId];
$scope.language.listIsOpen = !$scope.language.listIsOpen;
}
};
$scope.language.init();
You are iterating array from translation json file. This translation json file is loaded by $translate
service and you will not have access on loaded content, but you need the data from this json file to iterate it, thus you have to make your own request to fetch this array. Maybe you do not want but you have to make $http.get
call.
In your code one request is made by executing this line var lang = $translate.use(newLang);
and second call is done by $http.get
BUT in case if $http.get
is resolved before call in $translate.use
is resolved It will not translate content in dropdown because request in $translate.use
is not resolved yet and $translate
service does not have these translations to translate.
What you can do is to listen on $translateChangeSuccess
event (emitted by $translate
service) on $rootScope
and then make your ajax call in this handler.
I have tested the following code in your example and it works fine.
[UPDATED]
$rootScope.$on('$translateChangeSuccess', function () {
// Get new current new language
var lang = $translate.use();
$http.get('assets/i18n/'+lang+'.json').success(function(data) {
$scope.projectJSON = data;
});
});
For detailed explanation about events section on angular translate module, checkout this link.
Whenever you call $translate.use(localeId)
it will make ajax call internally and when this call is resolved it will emit $translateChangeSuccess
event, then you make your request, load data and update $scope.projectJSON
.
The only thing is to trigger this event first time, when you refresh browser, when $translate.use
is not called.
For this you can just call $translate.use
one time on page reload.
[UPDATED]
Put the following code at the end of your $scope.language.init
function.
$translate.use(proposedLanguage || preferredLanguage);
This should solve your problem.
这篇关于angularjs ng-repeat 来自不同 i18n 文件的下拉值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!