ExtJS MVC,动态加载和i18n

时间:2011-08-24 04:07:28

标签: extjs localization internationalization extjs4 extjs-mvc

我想用不同的语言翻译我的ExtJS应用程序。我的问题是我正在使用ExtJS MVC框架,我的大多数JS文件都是由框架本身动态下载的。

理想的解决方案(我想到的)是在Ext.Loader(或我的Ext.app.Application)中有一个额外的选项来定义要使用的语言,并根据这个选项自动下载这样的加载我的“a.MyClass.js”(包含Ext.apply,覆盖我的字符串资源)后,将文件命名为“a.MyClass.fr.js”。目前可能还没有在ExtJS框架中提供。

我可以看到的替代解决方案是在服务器端执行一个技巧。首先,将在客户端上创建一个cookie,以设置为该语言。在服务器端,我可以捕获对JS文件的所有请求,然后如果设置了cookie(例如='fr'),我将所请求的JS文件(MyClass.js)与其i18n的朋友(MyClass)组合在一起.fr.js)动态地在服务器上返回结果。这可行,但它真的很棘手,因为它意味着其他事情(缓存......)。

也许最好的方法是实现我自己在ExtJS框架中描述的第一个行为......

你怎么看?我正在寻找一种非常干净利落的方式!谢谢:))

4 个答案:

答案 0 :(得分:9)

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

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

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

2)下载覆盖每个组件的本地化文件(维护地狱?糟糕的译员怎么样?)

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

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

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

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

3)Prototyping String with 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'
});

服务器上的Bundle(mesages_en.properties): DOCUMENT_LIBRARY_MENU_COPYTO_BUTTON =复制文件 等。

优点:

  • 没有大惊小怪的代码,'Your_key'.translate()可以让您轻松阅读并知道这是一个本地化的字符串
  • 没有/很少维护开销(保留每个语言环境的覆盖文件?耶稣......)
  • 您只需加载您需要的语言环境 - 而不是整个shabang。
  • 如果您真的想要,您甚至可以在同一个捆绑包中为ExtJS区域设置文件创建自己的翻译。
  • 您可以编写单元测试以确保所有捆绑包含相同的密钥,从而避免以后出现孤立的翻译

缺点:

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:0)

您应首先完成开发阶段并构建项目或使用ext-all.js文件来转换您的UI

答案 3 :(得分:0)

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

您还可以在Loader路径中使用变量:

var lang='fr';
Loader
{
 paths:
 {
    'Ext': '.',  
    'My': './src/my_own_folder'+'/'+lang
 }