2012-04-15 56 views
0

我正在开发一个jQuery插件,它假装自动根据用户的浏览器语言来翻译页面上的元素。翻译将存储在.json文件中。如何返回将解决几个函数的结果?

当你调用插件,你传递一个包名(或它们的阵列),然后它会尝试加载语言文件以下列方式:

  • 如果浏览器的语言很简单,例如'en',你只表明一个包,它会尝试加载以下:packageName-en.json
  • 如果浏览器的语言组成,例如“EN-US”它会尝试加载和以前一样,但有:packageName-en.jsonANDpackageName-en-US.json
  • 如果显示了多个包,它将尝试按照每个包的前两个路径之一进行操作。

所以,在插件我有这样的:

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

问题是,由于该函数将被称为probabl y多次,我不知道如何让initialize返回一个承诺,一旦所有的函数被调用,这个承诺将被解决。

回答

2

我知道你接受了答案,但已经有一个更简单的方法:用$.when

function loadLanguages() { 
    return $.when.apply($, $.map(self.options.packages, function(pkg) { 
     return getLanguage(pkg, language); 
    })); 
} 
+0

虽然我接受了一个答案,但我认为你更好。这是我寻找的解决方案,而另一种方式似乎有点骇人听闻。非常感谢Julian :) – 2012-04-20 07:19:52

0

要解决此问题,您可以创建一个虚拟Deferrer(baseDfr)并返回虚拟结果为initialize()。这里的想法是当所有的getLanguage()调用完成后,致电baseDfr.resolve()。我们跟踪使用计数器完成的getLanguage()调用的数量。当计数器达到0时,我们呼叫baseDfr.resolve()。 我们知道何时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()."); 
});