【问题标题】:JS Globalize - load json cldrJS Globalize - 加载 json cldr
【发布时间】:2014-10-06 13:21:09
【问题描述】:

我对最新版本的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?

【问题讨论】:

    标签: javascript jquery json knockout.js cldr


    【解决方案1】:

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

    1. 使用$.ajaxasync: false 选项来加载您的json 模块。
    2. 使用 deferreds 对所有 ajax 请求进行一次回调。

    1.使用async: false

    您可以使用更通用的方法$.ajax 而不是$.get(请参阅description)。它有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

    【讨论】:

    • 感谢 when 函数。我想我现在必须构建一些通用的“初始化”函数,因为我不想在每个 vie 页面上插入这段代码。所以我认为最好的方法是将它放入布局页面并调用视图页面内的一些“viewinit”函数。嗯,这在旧的 globalize 版本上要容易得多。
    • @SteffenMangold,不客气!如果您使用了任何一种方法,请您接受答案吗?
    • 非常感谢@IlyaLuzyanin!这帮助很大。现在我只需要弄清楚如何在 done 函数中加载我的外部和内联脚本,因为它们依赖于 Globalize 正在加载......
    猜你喜欢
    • 2017-03-29
    • 2018-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多