ExtJS MVC, динамическая загрузка и i18n - PullRequest
5 голосов
/ 24 августа 2011

Я бы хотел перевести мое приложение ExtJS на разные языки.Моя проблема в том, что я использую среду ExtJS MVC, и большинство моих файлов JS загружаются динамически самой платформой.

Идеальным решением (о котором я думал) было бы иметь дополнительную опцию вExt.Loader (или в моем Ext.app.Application), который определит используемый язык, и в зависимости от этого автоматически загрузит такой файл как «a.MyClass.fr.js» после загрузки моего «a.MyClass.js»(который будет содержать Ext.apply, переопределяя мои строковые ресурсы).Это, вероятно, в данный момент недоступно в платформе ExtJS.

Альтернативное решение, которое я вижу, - это выполнить трюк на стороне сервера.Сначала на клиенте будет создан cookie для установки на язык.На стороне сервера я мог бы отлавливать все запросы к файлам JS, затем, если установлен cookie (например, 'fr'), я бы объединил запрошенный файл JS (MyClass.js) с другом его i18n (MyClass)..fr.js) динамически на сервере и возвращает результат.Это бы сработало, но это действительно сложно, потому что это подразумевает другие вещи (кеширование ...).

Может быть, лучший способ - реализовать первое поведение, которое я описал в среде ExtJS ...1008 * Что ты думаешь?Я ищу действительно чистый и аккуратный способ сделать это!Спасибо:)

Ответы [ 4 ]

9 голосов
/ 19 октября 2011

Я недавно боролся с той же проблемой.

Найти чистый способ сделать это было довольно сложной задачей - большинство альтернатив были либо ..

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 ключей / значений в каждом пакете) во время загрузки имеют размер около 10 КБ.

2 голосов
/ 05 сентября 2011

В настоящее время нет решения, поэтому я решил создать свой собственный хак / аддон на Ext.Loader. Я загрузил код на GitHub: https://github.com/TigrouMeow/extjs-locale-loader. Это именно то, что мне было нужно, и я очень надеюсь, что это поможет и другим!

0 голосов
/ 01 сентября 2011

см .: http://docs.sencha.com/ext-js/4-0/#!/example/locale/multi-lang.html Соответствующий скрипт модификатора языка (/ext/local/ext-lang-xxx.js) должен быть загружен после загрузки ext (включая динамически загружаемые классы).В приведенном выше примере я бы, вероятно, использовал Ext.Loader.loadScriptFile, но они напрямую скачивают скачанный.Единственное другое, что ваши классы должны быть построены на разных языках, или вы просто используете переменные и ссылаетесь на файл переменных, специфичный для lang.

вы также можете использовать переменную в путях загрузчика:

var lang='fr';
Loader
{
 paths:
 {
    'Ext': '.',  
    'My': './src/my_own_folder'+'/'+lang
 }
0 голосов
/ 29 августа 2011

Сначала вы должны завершить фазу разработки и создать проект или использовать файл ext-all.js, чтобы I18s перевел ваш пользовательский интерфейс

...