5

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

现在我从 globalize 文档中得到了这个例子:

// 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');

我现在的问题是本地 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);

在我真正使用全球化格式方法之前,这将起作用。在我的 HTML 中,我在敲除绑定中使用 globalize,如下所示:

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

现在“formatNumber”方法抛出错误,因为在绑定发生时并非所有模块都已加载。

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

4

1 回答 1

9

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

  1. 使用$.ajaxwithasync: 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);
    }
});

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

// set current language
lobalize.locale('de-de');

就像你以前做的一样。但是现在,由于所有请求都是同步完成的,这段代码应该可以按预期工作。这个解决方案的缺点是它有同步请求,这会导致一些延迟。这就是为什么我建议您使用第二种选择:

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
});

好消息是所有请求现在都是异步完成的。但这仍然不能解决您的淘汰赛绑定问题。要解决它,ko.applyBindings也应该在加载所有数据时在成功回调中调用。

于 2014-08-13T14:58:38.930 回答