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, который преобразует ваш пользовательский интерфейс