问题
I have a problem with the latest version of globalize.js
.
To work with it I had to load the cldr modules
and language definitions.
Now I had this example from the globalize docs:
// loading needed modules
$.get('/Scripts/cldr/supplemental/likelySubtags.json', Globalize.load);
$.get('/Scripts/cldr/main/en/numbers.json', Globalize.load);
$.get('/Scripts/cldr/main/de/numbers.json', Globalize.load);
// set current language
lobalize.locale('de-de');
My problem now is that the local json files are loaded async. That means at the moment where my script is try to set the current language, the modules are not yet loaded.
Now I tried to be smart and made this:
$.get('/Scripts/cldr/supplemental/likelySubtags.json', function (data) {
Globalize.load(data);
Globalize.locale('de-de');
});
$.get('/Scripts/cldr/main/en/numbers.json', Globalize.load);
$.get('/Scripts/cldr/main/de/numbers.json', Globalize.load);
This will work until I really used globalize format methode. Inside my HTML I use globalize inside a knockout binding like this:
<span data-bind="text: Globalize.formatNumber(SomeNumber, { maximumFractionDigits: 0 })"></span>
Now the "formatNumber" method is throwing an error because not all module are loaded at the moment the binding is happend.
My question is now, how can I sync up my JavaScript?
回答1:
There are actually 2 ways to solve the issue:
- Use
$.ajax
withasync: false
option to load your json modules. - Use deferreds to have a single callback on all your ajax requests.
1. Using async: false
You can use more general method $.ajax
instead of $.get
(see description). It has async
option:
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false.
So you can rewrite your requests as follows:
$.ajax({
url: '/Scripts/cldr/supplemental/likelySubtags.json',
type: 'GET',
async: false,
success: function(data) {
Globalize.load(data);
}
});
You do this for all 3 of your requests and then call:
// set current language
lobalize.locale('de-de');
Just like you did before. But now, since all requests are done synchronously, this code should work as expected. The downside of this solution is that it has synchronous requests which will cause some delays. That is why I suggest you the second option:
2. Using deferreds: You can use $.when() function to combine success callbacks of all three requests to one like this:
$.when($.get('/Scripts/cldr/supplemental/likelySubtags.json'),
$.get('/Scripts/cldr/main/en/numbers.json'),
$.get('/Scripts/cldr/main/de/numbers.json'))
.done(function(result1, result2, result3) {
Globalize.load(result1[0]); //contains data of first executed request
Globalize.load(result2[0]); //contains data of second executed request
Globalize.load(result3[0]); //contains data of third executed request
// set current language
lobalize.locale('de-de');
// here you should fire your knockout binding
});
The good thing is that all requests are now done asynchronously. But this would still not solve your knockout binding issue. To resolve it, ko.applyBindings
should also be called in success callback, when all data is loaded.
来源:https://stackoverflow.com/questions/25281816/js-globalize-load-json-cldr