2012-04-15 7 views
0

사용자의 브라우저 언어에 따라 자동으로 페이지의 요소를 가장하는 jQuery 플러그인을 개발 중입니다. 번역은 .json 파일에 저장됩니다. 당신이 플러그인을 호출 할 때여러 함수의 결과로 해결할 수있는 약속을 반환하는 방법은 무엇입니까?

, 당신은 패키지 이름 (또는 이들의 배열)을 통과 한 후 다음과 같은 방법으로 언어 파일을로드하려고합니다 : 브라우저의 언어가 간단

  • 경우, 예를 들어 'en'이고 패키지를 표시 한 경우에만 다음을로드하려고 시도합니다. packageName-en.json
  • 브라우저 언어가 'en-US'와 같이 구성된 경우 이전과 동일하게로드하려고 시도하지만 다음을 사용합니다. packageName-en.jsonpackageName-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

나는 이미 답을 인정하지만, 훨씬 더 간단한 방법이 알고있다.

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

나는 대답을 받아 들였지만 나는 너의 것이 더 낫다고 생각한다. 그것은 제가 찾고있는 해결책이고 다른 방법은 다소 해킹 된 것처럼 보입니다. 대단히 감사합니다 줄리안 :) –

0

이 문제를 해결하기 위해 더미 지연 자 (baseDfr)를 만들고 더미를 initialize()의 결과로 반환 할 수 있습니다. 여기서 아이디어는 getLanguage() 전화가 모두 완료되면 baseDfr.resolve()으로 전화하는 것입니다. 우리는 카운터를 사용하여 완료된 getLanguage() 전화의 번호를 추적합니다. 카운터가 0에 도달하면 baseDfr.resolve()이라고합니다. 전화가 $.ajax에 의해 then() 또는 done() 메서드를 사용하여 반환 된 지연 자에 대해 완료되면 알 수 있습니다.

이 문제를 해결하는 코드는 아래에서 확인할 수 있습니다. 또한 작동 예제 (일부 div)는 http://jsfiddle.net/c5NBr/에서 찾을 수 있습니다. 메시지를 올바른 순서로 표시하려면 콘솔을 엽니 다. $.when를 사용

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()."); 
}); 
관련 문제