5

I would like to translate my ExtJS application in different languages. My issue is that I'm using ExtJS MVC framework, and most of my JS files are downloaded dynamically by the framework itself.

The ideal solution (that I thought of) would be to have an extra option in the Ext.Loader (or in my Ext.app.Application) that would define the language to use, and depending on this to automatically download such file as "a.MyClass.fr.js" after loading my "a.MyClass.js" (which would contain an Ext.apply, overriding my string resources). That's probably not available in the ExtJS framework at the moment.

The alternative solution I can see, is to perform a trick on the server-side. First, a cookie would be created on the client, to set to the language. On the server-side, I could catch all the requests to JS files, then if a cookie is set (='fr' for example), I'd combine the requested JS file (MyClass.js) with its i18n's friend (MyClass.fr.js) dynamically on the server and return the result. That would work, but it's really tricky because it implies other things (caching...).

Maybe the best way is to implement the first behavior I described in the ExtJS framework myself...

What do you think? I'm looking for a really clean and neat way of doing it! Thanks :)

4

4 回答 4

9

我最近遇到了同样的问题。

找到一种干净的方法来做到这一点是一个相当大的挑战——大多数替代方案要么......

1) 每个区域复制你的代码库 (WTH)

2)下载覆盖每个组件的本地化文件(维护地狱?可怜的翻译呢?)

3) 使用/生成包含翻译的静态文件并引用它(所有语言都已下载?生成它的额外构建步骤?如何使它们保持同步?)

我试图获得所有世界中最好的,并最终得到了一个实用程序类,负责:

1) 加载 ExtJS 翻译文件(基本上将覆盖应用于 extjs 基础组件)

2) 从服务器加载特定于语言环境的属性资源包(指定要加载的语言环境)。

3) 使用 translate() 方法查询加载的存储(包含来自服务器的消息包)并根据字符串的值返回翻译的原型字符串。

这是事情的要点:

捆绑和原型制作:

localeStore.load({
    callback : function(records, operation, success) {
        // Define translation function (NB! Must be defined before any components which want to use it.)
        function translate() {
            var record = localeStore.getById(this.valueOf()) ;
            if(record === null) {
                alert('Missing translation for: ' + this.valueOf()); // Key is not found in the corresponding messages_<locale>.properties file.
                return this.valueOf(); // Return key name as placeholder
            } else {
                var value = record.get('value');
            }
            return value;
        }

        String.prototype.translate = translate;
        callback.call(); // call back to caller(app.js / Ext.Application), loading rest of application
    }
});

举个例子:

this.copyButton = Ext.create('Ext.button.Button', {
    disabled: true,
    text: 'DOCUMENT_LIBRARY_MENU_COPYTO_BUTTON'.translate(),
    action: 'openCopyDialog'
});

在服务器上捆绑(mesages_en.properties):DOCUMENT_LIBRARY_MENU_COPYTO_BUTTON=复制文件等。

优点:

  • 简洁的代码,'Your_key'.translate() 使其易于阅读并意识到这是一个本地化字符串
  • 无/很少的维护开销(为每个语言环境保留一个覆盖文件?天啊..)
  • 你只加载你需要的语言环境——而不是整个沙班。
  • 如果你真的想要,你甚至可以在同一个包中为 ExtJS 语言环境文件提供自己的翻译。
  • 您可以编写单元测试以确保所有捆绑包都包含相同的键,从而避免以后出现孤立的翻译

缺点:

  • 同步 - 商店必须在您的主应用程序启动之前加载。我通过从实用程序类中添加一个回调来解决这个问题,一旦加载了所有文本,该回调就会被调用。
  • 没有实时文本填充..虽然我也不想让我的用户超载服务器:P

到目前为止,我的方法已经很好地满足了我的要求。站点加载速度并没有明显变慢,并且捆绑包(每个捆绑包包含约 200 个键/值)在加载期间的大小约为 10kb。

于 2011-10-19T12:46:46.953 回答
2

目前没有解决方案,所以我决定在 Ext.Loader 上创建自己的 hack/addon。我在 GitHub 上上传了代码:https ://github.com/TigrouMeow/extjs-locale-loader 。这正是我所需要的,我真的希望它也能帮助其他人!

于 2011-09-05T00:49:17.190 回答
0

请参阅:http ://docs.sencha.com/ext-js/4-0/#!/example/locale/multi-lang.html 适当的语言修饰符脚本(/ext/local/ext-lang-xxx.js ) 需要在加载 ext 后加载(包括动态加载的类)。在上面的示例中,我可能会使用 Ext.Loader.loadScriptFile 但他们直接评估下载的文件。唯一的另一件事是您的类需要用不同的语言构建,或者您只需使用变量并引用特定于语言的变量文件。

您还可以在加载程序路径中使用变量:

var lang='fr';
Loader
{
 paths:
 {
    'Ext': '.',  
    'My': './src/my_own_folder'+'/'+lang
 }
于 2011-09-01T04:38:45.400 回答
0

您应该首先完成您的开发阶段并构建您的项目或使用 ext-all.js 文件到 I18s 翻译您的 UI

于 2011-08-29T11:58:36.127 回答