2013-10-27 13 views
5

翻訳をサポートする必要があるRequireJS上に構築された単一ページのMarionetteアプリケーションがあります。ロケールファイルを動的にロードするRequirejsを使用して

私の目標は、言語ごとに辞書ファイルを用意し、ログインしたユーザーの設定に基づいて関連ファイルを読み込むことです。

ほとんどのユーザーは英語を使用するため、英語の辞書をビルド中に(r.jsを使用して)アプリケーションにバンドルしたいと思っています。

私は基本的にjed.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(); 
}); 

あなたが見ることができるように、ロケールデータは静的なファイルからロードされます。 ロケールをTranslatorコンストラクタに渡し、それに基づいて正しいJSONファイルをロードしたいと考えています。

ビルドされたプロジェクトに英語のJSONをバンドルしておくとどうしたらいいですか?

答えて

1

これは私がやった解決策です。 それはとてもうまく動いていて、$。ディフェレッドの使い方も学びました。

私のためのキーは、コードのローダーとしてrequire textプラグインを使用していました。

デフォルトのロケールは依存関係として設定されているため、ビルドでも焼き付けられます。返信用

//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

(またはif (userLocale !== 'en_US') { require([path], function(locale) {...})のように、翻訳モジュール内の同じことを行う)

理論的にはそれが動作するはずです、ここにかかわらず、あなたcannot use simplified CommonJSとコールバック-必要を使用する必要があり、そうでなければ、Module name ... has not been loaded yet for contextエラーが発生します。

+0

おかげで、私は少し違う何かをやってしまった:

説明は以下のコードです。あなたは私の答えを以下に見ることができます – elanh

関連する問題