0

ユーザーのブラウザ言語に応じて、ページ上の要素を自動的に翻訳するふりをする jQuery プラグインを開発しています。翻訳は .json ファイルに保存されます。

プラグインを呼び出すときに、パッケージ名 (またはそれらの配列) を渡すと、次の方法で言語ファイルをロードしようとします。

  • たとえば、ブラウザの言語が単純で'en'、パッケージのみを指定した場合、ブラウザは次のものをロードしようとします。packageName-en.json
  • ブラウザーの言語が構成されている場合 (たとえば、「en-US」)、以前と同じものを読み込もうとしますが、次のものを使用しますpackageName-en.json packageName-en-US.json
  • 複数のパッケージが指定されている場合、パッケージごとに前の 2 つのパスのいずれかをたどろうとします。

したがって、プラグインには次のものがあります。

$.fn.Translator = function(pkg, options){
    Translator.initialize(pkg, options).done(function(){
        return this.each(Translator.translate);
     });            
};

だから、私の初期化関数のどこかに、私はこれを持っています:

loadLanguages : function(){
    $.each(self.options.packages,function(i, pkg){

    });
}

この関数を呼び出すもの:

getLanguage : function(pkg, language){
    var self = this, url;
    if (self.options.path)
        url = self.options.path + '/';
    url += [pkg, language].join('-');

    return $.ajax ({
        url : url,
        dataType : "json",
        cache : self.options.cache
    });
}

initialize問題は、その関数がおそらく複数回呼び出されるため、すべての関数が呼び出されると解決される promise を返す方法がわからないことです。

4

2 に答える 2

2

すでに回答を受け入れていることは知っていますが、もっと簡単な方法があります。 $。whenを使用します。

function loadLanguages () {
    return $.when.apply( $, $.map( self.options.packages, function( pkg ) {
        return getLanguage(pkg, language);
    }) );
}
于 2012-04-20T05:40:44.233 に答える
0

この問題を解決するには、ダミーの Deferrer (baseDfr) を作成し、ダミーを の結果として返しinitialize()ます。ここでの考え方はbaseDfr.resolve()、すべてのgetLanguage()呼び出しが完了したときに呼び出すことです。getLanguage()カウンターを使用して行われた呼び出しの数を追跡します。カウンターが 0 になったら、 を呼び出しますbaseDfr.resolve()。返された deferr by でorメソッドを使用して、いつgetLanguage()呼び出しが完了したかがわかります。then()done()$.ajax

これを解決するコードは以下にあります。また、実際の例 (一部の div) はhttp://jsfiddle.net/c5NBr/にあります。コンソールを開いて、メッセージが正しい順序で表示されることを確認します。

var packages = [];
var count = 0;
var baseDfr = $.Deferred();
var language = "en";

function resolveFunction () {
    // By using this approach it is possible to pass a 
    // parameter to this resolve function.
    return function(){
        if ( !(--count) ) {
            // Until count is 0, we won't resolve the base
            // deferrer object.
            // As long as this isn't called, the function
            // done() of initialize won't be called either.
            baseDfr.resolve();
        }     
    };
}

function getLanguage (pkg, language){
    var self = this, url;
    if (self.options.path)
        url = self.options.path + '/';
    url += [pkg, language].join('-');

    return $.ajax ({
        url : url,
        dataType : "json",
        cache : self.options.cache
    }).promise();
}

function loadLanguages () {
    $.each(self.options.packages,function(i, pkg){
        getLanguage(pkg, language).then(resolveFunction());
    });

    return baseDfr.promise();                
}

function initialize(options) {
    packages = options.packages;
    count = options.packages.length;    

    return loadLanguages();
}

var options =  {
    packages : $('div')          
};

initialize(options).done(function(){
    // This will only be called when baseDfr.resolve() is called.
    console.log("Fired all getLanguage().");
});
于 2012-04-15T21:02:33.020 に答える