ExtJS MVC, динамическая загрузка и i18n

5 TigrouMeow [2011-08-24 07:07:00]

Я хотел бы перевести приложение 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, сам...

Как вы думаете? Я ищу действительно чистый и аккуратный способ сделать это! Спасибо:)

internationalization localization extjs extjs4 extjs-mvc


4 ответа


9 Решение JaySee [2011-10-19 15:46:00]

Недавно я столкнулся с одной и той же проблемой.

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

1) Дублируйте свою базу кода для каждой локали (WTH)

2) Загрузите локализованные файлы, переопределяющие каждый из ваших компонентов (поддерживая ад? Что относительно бедных переводчиков?)

3) Использовать/генерировать статический файл, содержащий переводы и ссылаться на него (все языки загружаются?) Дополнительная команда сборки для ее создания? Как вы их синхронизируете?)

Я попытался получить лучшее из всех миров и получил класс утилиты, ответственный за:

1) Загрузка файлов перевода ExtJS (которые в основном применяют переопределения к базовым компонентам extjs)

2) Загрузка специфического ресурса ресурса resourcebundle (указав, какой язык для загрузки) с сервера.

3) Прототипирование String с помощью метода 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 ключей/значений на пучок) измеряют при ~ 10 кбайт во время загрузки.


2 TigrouMeow [2011-09-05 03:49:00]

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


0 Peter Hawkins [2011-09-01 07:38:00]

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

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

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

0 PHPst [2011-08-29 14:58:00]

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