admin管理员组文章数量:1426782
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 e 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) es 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();
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 e 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) es 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();
Share
Improve this question
asked Oct 23, 2016 at 1:44
cpluscplus
1,1154 gold badges25 silver badges57 bronze badges
12
- Try to use promise pattern: $http.get(..).then(function(response){..}) – Vadim Commented Oct 26, 2016 at 18:49
- @Vadim please write down your suggestion as a plete answer. – cplus Commented Oct 26, 2016 at 18:49
- hey would it be possible for you put them together and put on a code snippet or plunkr, in working state to checkout? – Sreekanth Commented Oct 26, 2016 at 19:02
- @Mpondomise, did you solve your problem? – Max Koretskyi Commented Oct 26, 2016 at 19:11
- @Maximus not yet! I am still looking for solution. Do you have any? – cplus Commented Oct 26, 2016 at 19:15
5 Answers
Reset to default 2 +150You 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.
Try to use promise pattern:
$http.get(..).then(function(response){..})
So, looks like problem not in ng-repeat
, so I would change the title of the question. Back to the subject:
$http.get('assets/i18n/'+lang+'.json').then(function(response) {
//check what exactly are you getting in the response
//console.log(response)
$scope.projectJSON = response;
});
And I would check what is the response
actually, probably, you need to do
$scope.projectJSON = response.data;
Old
Because you are using an async function angular won't recognize the change immediately. After downloading the files add
$scope.$apply();
To make angular rescan everything and apply changes. Here you can read more about it.
That means for you ($$phase check by @lascort)
$http.get('assets/i18n/'+lang+'.json').success(function(data) {
$scope.projectJSON= data;
$translate.use(lang);
if (!$scope.$$phase)
$scope.$apply();
$translate.refresh();
});
Edit
But official resources remend to use their loaders and not load manually: Here
You are using a staticFilesLoader so install the following extension:
bower install angular-translate-loader-static-files
Then in your language change function:
$translateProvider.preferredLanguage(lang);
This should work (says the documentation). Maybe you have to do a $scope.$apply();
but I think this is already included.
Lets go through step by step:
1) The translate="project.SPONSORINFO.MAIN" in the label is rightly showing the value "Select the Sponsor Name" without refresh needed
2) the dropdown menus don't get changed to the selected language unless you refresh or change view and e back.
So, the toggle for translation is actually working.
But why it does not work for dropdown menus?
One thing we can note is that label for project.SPONSORINFO.MAIN
is a static text while s.spons
is dynamic based on value return.
The select option is being piled first time when entering the page and not being repiled after you toggle your languages changes. As such, when you toggle the translation, you retrieve the text, but the select option element is not being repiled and thus not being translated on the fly till your next reentering/reload of the view.
You have few ways to solve the problem:
1) programmitically refresh the state/route once translate is plete. (quick fix but bad way)
2) Write an angular directive that repile the element once detect language changes. (better approach)
An idea of how to achieve second solution:
var lang = $translate.use();
$http.get('assets/i18n/'+lang+'.json').success(function(data) {
$scope.projectJSON= data;
$scope.newLanguage = $translate.use();
});
.directive('repileLanguage', function($pile) {
return {
restrict: 'E',
scope: {
lang: '='
},
link: function(scope, element, attr) {
$pile(element.contents())(scope);
scope.$watch('lang', funcion (newValue, oldvalue) {
$pile(element.contents())(scope);
});
}
}
});
<select repile-language lang={{newLanguage}}> </select>
Have you tried reloading the state?
$state.reload();
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;
},
uiReload: function(){
$state.reload();
}
};
$scope.language.init();
$scope.language.uiReload(); //call this for ui-router
本文标签: javascriptangularjs ngrepeat the dropdown values from different i18n filesStack Overflow
版权声明:本文标题:javascript - angularjs ng-repeat the dropdown values from different i18n files - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745485969a2660384.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论