【问题标题】:ExtJS MVC, dynamic loading and i18nExtJS MVC、动态加载和 i18n
【发布时间】:2011-08-24 04:07:28
【问题描述】:

我想将我的 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 框架中描述的第一个行为...

你怎么看?我正在寻找一种非常干净整洁的方法!谢谢:)

【问题讨论】:

    标签: extjs localization internationalization extjs4 extjs-mvc


    【解决方案1】:

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

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

    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() 使其易于阅读并意识到这是一个本地化字符串
    • 没有/很少的维护开销(为每个语言环境保留一个覆盖文件?天啊..)
    • 您只加载您需要的语言环境 - 而不是整个 shabang。
    • 如果您真的愿意,您甚至可以在同一个包中为 ExtJS 语言环境文件提供自己的翻译。
    • 您可以编写单元测试以确保所有包都包含相同的键,从而避免以后出现孤立的翻译

    缺点:

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

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

    【讨论】:

    • Thanx JaySee,很好的原型方法,使代码阅读起来很愉快,并且仍然提供简单的翻译方法!
    • 感谢优雅的解决方案。如果使用Ext.ux.Cache,Cons 可以改为 Pros
    【解决方案2】:

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

    【讨论】:

    • 可能有多种语言的组合,当用户更改组合值时,所有应用程序都会加载语言环境资源以更新语言???谢谢
    【解决方案3】:

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

    【讨论】:

    • 我希望我的 i18n 在开发阶段和之后由系统正确管理。不同的人在不同的课程上工作,每个人都会带着他们的翻译文件。它也必须易于更新。当前找到的所有解决方案都不适合这种情况。
    【解决方案4】:

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

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

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

    【讨论】:

    • 但这仍然意味着我需要在最后加载一个包含所有翻译的大文件,不是吗?我想为我的每个班级提供语言环境文件(让我们看看,每个视图或每个控制器)。我实际上开发了一些东西并且它有效,我应该将它上传到 github 上吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-07
    相关资源
    最近更新 更多