2013-10-27 4 views
5

번역을 지원해야하는 RequireJS를 기반으로하는 단일 페이지 마리오 네트 앱이 있습니다.요구 사항을 사용하여 동적으로 로켈 파일로드

내 목표는 각 언어에 대한 사전 파일을 가지고 로그인 한 사용자의 구성에 따라 관련 파일을로드하는 것입니다.

대부분의 사용자가 영어를 사용할 것이므로 빌드 중에 (r.js를 사용하여) 앱에 영어 사전을 번들로 제공하고 싶습니다. 당신이 볼 수 있듯이

//in myTranslator.js 
define(function (require) { 
    "use strict"; 

    var Jed = require("jed"); 
    var localeData = require("json!locales/en_US.json"); 

    var Translator = function() { 
     var i18n = new Jed({ 
      "domain": "messages", 
      "locale_data": localeData 
     }); 
     return i18n; 
    }; 
    return Translator; 
}); 

//in app.js 
define(function(require){ 
    var Translator = require("myTranslator"); 
    var translator = new Translator(); 
}); 

, 로케일 데이터가 정적 파일에서로드 :

나는 기본적으로 (라이브러리 내가 국제화를 위해 사용하고 있습니다) jed.js를 감싸는 작은 번역기 모듈을 썼다. 로케일에서 Translator 생성자로 전달할 수 있고이를 기반으로 올바른 JSON 파일을로드하고 싶습니다.

영어 JSON을 빌드 된 프로젝트에 묶어 두는 것과 함께 어떻게 할 수 있습니까?

답변

1

이것은 결국 내가 한 솔루션입니다. 매우 훌륭하게 작동했으며, $ .Deferred를 사용하는 방법에 대해서도 배웠습니다.

나를위한 열쇠는 코드에서 로더로 필수 텍스트 플러그인을 사용하는 것이 었습니다.

기본 로캘은 종속성으로 설정되므로 빌드에서도 구워집니다. 답장을

//in translator.js 
define(function (require) { 
    "use strict"; 

    var $ = require("jquery"); 
    var _ = require("underscore"); 
    var Jed = require("jed"); 
    var text = require("text"); 
    var defaultDictionary = require("json!locales/en_US.json"); 

    var Translator; 

    Translator = (function() { 
     var DEFAULT_LOCALE = "en_US"; 
     var defaultLocaleData = { 
      locale: DEFAULT_LOCALE, 
      dictionary: defaultDictionary 
     }; 

     var createTranslator = function (localeData) { 
      //create the actual Jed instance with the relevant dictionary 
      var i18n = new Jed({ 
       "domain": "messages", 
       "locale_data": localeData.dictionary 
      }); 
      return i18n; 
     }; 
     var parseLocaleDictionary = function (locale, dictionary) { 
      //parse the dictionary JSON string loaded by text plugin... 
      //handle errors in parsing if needed 
     }; 
     //get to work here 
     var getTranslatorForLocale = function (locale) { 
      //$gettingData promise will be resolved when data for Jed is loaded and ready 
      var $gettingData = $.Deferred(); 
      //$creatingTranslator promise will be returned to caller and will be resolved when everything's done 
      var $creatingTranslator = $.Deferred(); 

      if (!locale || locale === DEFAULT_LOCALE) { 
       //default locale, so resolve right away because we required it already 
       $gettingData.resolve(defaultLocaleData); 
      } 
      else { 
       //need to load the dictionary from here 
       var dictionaryUrl = require.toUrl("locales/" + locale + ".json"); 
       //this is the dynamic loading 
       text.get(
        dictionaryUrl, 
        function (dictionary) { 
         //if successful, parse the JSON string and use that dictionary 
         var localeData = parseLocaleDictionary(locale, dictionary); 
         $gettingData.resolve(localeData); 
        }, 
        function (error) { 
         //on load error, use the default and resolve promise 
         $gettingData.resolve(defaultLocaleData); 
        }); 
      } 

      //once the data is ready, we can create the translator instance 
      $gettingData.done(function (localeData) { 
       var i18n = createTranslator(localeData); 
       //notify caller that translator is ready 
       $creatingTranslator.resolve(i18n); 
      }); 

      return $creatingTranslator.promise(); 
     }; 

     return { 
      //this function is returned to the user of Translator 
      getTranslator: function (locale) { 
       var $gettingTranslator = getTranslatorForLocale(locale); 
       return $gettingTranslator; 
      } 
     }; 
    }()); 

    return Translator; 
}); 
//in app.js 
define(function (require) { 
    var Translator = require("translator"); 
    //in app.js 
    var myTranslator; 
    var userLocale = "fr_FR"; 
    //this is a promise that will be resolved when translator is ready 
    var $getTranslator = Translator.getTranslator(userLocale); 
    //when translator is ready, store it 
    $getTranslator.done(function (translator) { 
     myTranslator = translator; 
    }); 
    //... 
}); 
4

사용자 설정을 확인하고 종속성 문자열을 생성하여 Translator에 전달한 다음 localeData 대신 사용할 수 있어야합니다. r.js는 동적 종속성을 무시하지만 EN 로캘을 묶어야합니다.

if (userLocale && userLocale !== 'en_US') { 

    var localePath = 'json!locales/' + userLocale + '.json'; 
    require([ localePath ], function(locale) { 
     var translator = new Translator(locale); 
    }); 

} 

및 내부 역자 : "locale_data": passedData || englishData.

그렇지 않으면 Module name ... has not been loaded yet for context 오류가 발생합니다, 여기에 작동해야 이론적으로

당신 생각 cannot use simplified CommonJS을 (또는 if (userLocale !== 'en_US') { require([path], function(locale) {...})처럼 번역기 모듈 내부의 동일 할) 및 콜백-필요로 사용해야합니다.

+0

감사합니다,하지만 난 조금 다른 뭔가를하고 결국 :

설명은 아래 코드에 있습니다. 내 대답은 아래에서 볼 수 있습니다. – elanh