JS Globalize - 加载json cldr

Ste*_*old 5 javascript jquery json knockout.js cldr

我的最新版本有问题globalize.js.要使用它,我必须加载cldr modules和语言定义.

现在我从全球化文档中得到了这个例子:

// 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');
Run Code Online (Sandbox Code Playgroud)

我现在的问题是本地json文件加载异步.这意味着在我的脚本尝试设置当前语言的那一刻,模块尚未加载.

现在我试着变得聪明并做到了这一点:

$.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);
Run Code Online (Sandbox Code Playgroud)

这将一直有效,直到我真正使用全球化格式方法.在我的HTML里面,我在一个淘汰赛绑定中使用全局化,如下所示:

<span data-bind="text: Globalize.formatNumber(SomeNumber, { maximumFractionDigits: 0 })"></span>
Run Code Online (Sandbox Code Playgroud)

现在"formatNumber"方法抛出错误,因为在绑定发生时并非所有模块都被加载.

我现在的问题是,如何同步我的JavaScript?

Ily*_*nin 9

实际上有两种方法可以解决这个问题:

  1. 使用$.ajax带有async: false选项装载JSON模块.
  2. 使用deferreds对所有ajax请求进行单次回调.

1.使用 async: false

您可以使用更通用的方法$.ajax代替$.get(请参阅说明).它有async选项:

默认情况下,所有请求都是异步发送的(默认情况下设置为true).如果需要同步请求,请将此选项设置为false.

因此,您可以按如下方式重写您的请求:

$.ajax({
    url: '/Scripts/cldr/supplemental/likelySubtags.json',
    type: 'GET',
    async: false,
    success: function(data) {
        Globalize.load(data);
    }
});
Run Code Online (Sandbox Code Playgroud)

您为所有3个请求执行此操作,然后致电:

// set current language
lobalize.locale('de-de');
Run Code Online (Sandbox Code Playgroud)

就像你之前做过的那样.但是现在,由于所有请求都是同步完成的,因此该代码应该按预期工作.该解决方案的缺点是它具有同步请求,这将导致一些延迟.这就是为什么我建议你第二个选择:

2.使用延迟: 您可以使用$.when()函数将所有三个请求的成功回调组合成如下所示:

$.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
});
Run Code Online (Sandbox Code Playgroud)

好处是所有请求现在都是异步完成的.但这仍然无法解决你的淘汰赛绑定问题.要解决它,ko.applyBindings还应该在加载所有数据时成功回调.