JS Globalize - load json cldr

旧城冷巷雨未停 提交于 2019-12-07 06:52:04

问题


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:

  1. Use $.ajax with async: false option to load your json modules.
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!